summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/static_checks.yml2
-rw-r--r--.gitignore3
-rw-r--r--.lgtm.yml7
-rw-r--r--.mailmap1
-rw-r--r--AUTHORS.md1
-rw-r--r--CHANGELOG.md2
-rw-r--r--COPYRIGHT.txt4
-rw-r--r--DONORS.md86
-rw-r--r--README.md1
-rw-r--r--SConstruct31
-rw-r--r--core/SCsub2
-rw-r--r--core/bind/core_bind.cpp5
-rw-r--r--core/bind/core_bind.h1
-rw-r--r--core/color.cpp134
-rw-r--r--core/color.h2
-rw-r--r--core/cowdata.h2
-rw-r--r--core/crypto/crypto_core.cpp20
-rw-r--r--core/crypto/crypto_core.h2
-rw-r--r--core/func_ref.cpp5
-rw-r--r--core/func_ref.h1
-rw-r--r--core/hashfuncs.h2
-rw-r--r--core/image.cpp76
-rw-r--r--core/image.h13
-rw-r--r--core/input/SCsub1
-rw-r--r--core/input/gamecontrollerdb.txt123
-rw-r--r--core/input/input_map.cpp2
-rw-r--r--core/io/compression.cpp87
-rw-r--r--core/io/compression.h3
-rw-r--r--core/io/file_access_encrypted.cpp73
-rw-r--r--core/io/file_access_encrypted.h9
-rw-r--r--core/io/file_access_pack.cpp82
-rw-r--r--core/io/file_access_pack.h20
-rw-r--r--core/io/file_access_zip.cpp11
-rw-r--r--core/io/file_access_zip.h12
-rw-r--r--core/io/ip_address.cpp4
-rw-r--r--core/io/json.cpp20
-rw-r--r--core/io/json.h8
-rw-r--r--core/io/pck_packer.cpp191
-rw-r--r--core/io/pck_packer.h14
-rw-r--r--core/io/resource_loader.cpp6
-rw-r--r--core/io/xml_parser.cpp4
-rw-r--r--core/list.h40
-rw-r--r--core/math/audio_frame.h2
-rw-r--r--core/math/basis.cpp21
-rw-r--r--core/math/basis.h23
-rw-r--r--core/math/expression.cpp20
-rw-r--r--core/math/expression.h2
-rw-r--r--core/math/math_funcs.h19
-rw-r--r--core/math/quat.h2
-rw-r--r--core/math/random_pcg.h5
-rw-r--r--core/math/vector2.h8
-rw-r--r--core/math/vector3.h16
-rw-r--r--core/message_queue.h3
-rw-r--r--core/method_bind.h14
-rw-r--r--core/object.h2
-rw-r--r--core/os/file_access.cpp8
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h6
-rw-r--r--core/project_settings.cpp6
-rw-r--r--core/project_settings.h2
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/string_buffer.h24
-rw-r--r--core/string_builder.cpp4
-rw-r--r--core/string_name.cpp2
-rw-r--r--core/string_name.h2
-rw-r--r--core/translation_po.h2
-rw-r--r--core/type_info.h3
-rw-r--r--core/ustring.cpp1114
-rw-r--r--core/ustring.h182
-rw-r--r--core/variant.cpp4
-rw-r--r--core/variant.h5
-rw-r--r--core/variant_call.cpp123
-rw-r--r--core/variant_internal.h118
-rw-r--r--core/variant_op.cpp86
-rw-r--r--core/variant_parser.cpp34
-rw-r--r--core/variant_parser.h8
-rw-r--r--core/vector.h2
-rw-r--r--doc/classes/@GlobalScope.xml8
-rw-r--r--doc/classes/AABB.xml6
-rw-r--r--doc/classes/AESContext.xml43
-rw-r--r--doc/classes/AStar.xml89
-rw-r--r--doc/classes/AStar2D.xml72
-rw-r--r--doc/classes/AcceptDialog.xml1
-rw-r--r--doc/classes/AnimatedSprite2D.xml1
-rw-r--r--doc/classes/Animation.xml17
-rw-r--r--doc/classes/AnimationNode.xml2
-rw-r--r--doc/classes/AnimationNodeAdd2.xml2
-rw-r--r--doc/classes/AnimationNodeAdd3.xml2
-rw-r--r--doc/classes/AnimationNodeAnimation.xml2
-rw-r--r--doc/classes/AnimationNodeBlend2.xml2
-rw-r--r--doc/classes/AnimationNodeBlend3.xml2
-rw-r--r--doc/classes/AnimationNodeBlendSpace1D.xml2
-rw-r--r--doc/classes/AnimationNodeBlendSpace2D.xml2
-rw-r--r--doc/classes/AnimationNodeBlendTree.xml2
-rw-r--r--doc/classes/AnimationNodeOneShot.xml2
-rw-r--r--doc/classes/AnimationNodeOutput.xml2
-rw-r--r--doc/classes/AnimationNodeStateMachine.xml12
-rw-r--r--doc/classes/AnimationNodeStateMachinePlayback.xml12
-rw-r--r--doc/classes/AnimationNodeStateMachineTransition.xml13
-rw-r--r--doc/classes/AnimationNodeTimeScale.xml2
-rw-r--r--doc/classes/AnimationNodeTimeSeek.xml2
-rw-r--r--doc/classes/AnimationNodeTransition.xml2
-rw-r--r--doc/classes/AnimationPlayer.xml6
-rw-r--r--doc/classes/AnimationTree.xml4
-rw-r--r--doc/classes/Area2D.xml6
-rw-r--r--doc/classes/Area3D.xml4
-rw-r--r--doc/classes/Array.xml87
-rw-r--r--doc/classes/ArrayMesh.xml27
-rw-r--r--doc/classes/AudioEffectDistortion.xml5
-rw-r--r--doc/classes/AudioEffectFilter.xml3
-rw-r--r--doc/classes/AudioEffectHighShelfFilter.xml2
-rw-r--r--doc/classes/AudioEffectLowShelfFilter.xml2
-rw-r--r--doc/classes/AudioEffectRecord.xml2
-rw-r--r--doc/classes/AudioServer.xml2
-rw-r--r--doc/classes/AudioStream.xml2
-rw-r--r--doc/classes/AudioStreamGenerator.xml2
-rw-r--r--doc/classes/AudioStreamGeneratorPlayback.xml2
-rw-r--r--doc/classes/AudioStreamPlayer.xml2
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml2
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml3
-rw-r--r--doc/classes/BaseButton.xml4
-rw-r--r--doc/classes/BaseMaterial3D.xml2
-rw-r--r--doc/classes/Basis.xml4
-rw-r--r--doc/classes/Button.xml21
-rw-r--r--doc/classes/CPUParticles2D.xml2
-rw-r--r--doc/classes/Callable.xml21
-rw-r--r--doc/classes/CanvasItem.xml17
-rw-r--r--doc/classes/CanvasLayer.xml4
-rw-r--r--doc/classes/CharFXTransform.xml15
-rw-r--r--doc/classes/CheckBox.xml1
-rw-r--r--doc/classes/CheckButton.xml1
-rw-r--r--doc/classes/ClippedCamera3D.xml2
-rw-r--r--doc/classes/CodeEdit.xml203
-rw-r--r--doc/classes/CollisionShape2D.xml2
-rw-r--r--doc/classes/CollisionShape3D.xml4
-rw-r--r--doc/classes/Color.xml265
-rw-r--r--doc/classes/ColorPickerButton.xml1
-rw-r--r--doc/classes/ColorRect.xml9
-rw-r--r--doc/classes/ConfigFile.xml22
-rw-r--r--doc/classes/ConfirmationDialog.xml9
-rw-r--r--doc/classes/Control.xml243
-rw-r--r--doc/classes/Crypto.xml55
-rw-r--r--doc/classes/Dictionary.xml2
-rw-r--r--doc/classes/DirectionalLight3D.xml2
-rw-r--r--doc/classes/Directory.xml2
-rw-r--r--doc/classes/DisplayServer.xml24
-rw-r--r--doc/classes/DynamicFont.xml2
-rw-r--r--doc/classes/EditorExportPlugin.xml12
-rw-r--r--doc/classes/EditorFeatureProfile.xml10
-rw-r--r--doc/classes/EditorImportPlugin.xml2
-rw-r--r--doc/classes/EditorNode3DGizmoPlugin.xml2
-rw-r--r--doc/classes/EditorPlugin.xml2
-rw-r--r--doc/classes/EditorScenePostImport.xml2
-rw-r--r--doc/classes/Environment.xml69
-rw-r--r--doc/classes/Expression.xml2
-rw-r--r--doc/classes/File.xml13
-rw-r--r--doc/classes/FileDialog.xml1
-rw-r--r--doc/classes/Font.xml2
-rw-r--r--doc/classes/GIProbe.xml2
-rw-r--r--doc/classes/GPUParticles2D.xml4
-rw-r--r--doc/classes/GPUParticles3D.xml32
-rw-r--r--doc/classes/GridContainer.xml7
-rw-r--r--doc/classes/HTTPClient.xml9
-rw-r--r--doc/classes/HTTPRequest.xml48
-rw-r--r--doc/classes/Image.xml2
-rw-r--r--doc/classes/ImageTexture3D.xml39
-rw-r--r--doc/classes/Input.xml17
-rw-r--r--doc/classes/InputEvent.xml4
-rw-r--r--doc/classes/InputEventAction.xml2
-rw-r--r--doc/classes/InputEventJoypadButton.xml2
-rw-r--r--doc/classes/InputEventJoypadMotion.xml2
-rw-r--r--doc/classes/InputEventKey.xml2
-rw-r--r--doc/classes/InputEventMouse.xml2
-rw-r--r--doc/classes/InputEventMouseButton.xml2
-rw-r--r--doc/classes/InputEventMouseMotion.xml2
-rw-r--r--doc/classes/InputEventScreenDrag.xml2
-rw-r--r--doc/classes/InputEventScreenTouch.xml2
-rw-r--r--doc/classes/InputEventWithModifiers.xml2
-rw-r--r--doc/classes/InputMap.xml2
-rw-r--r--doc/classes/JavaScript.xml3
-rw-r--r--doc/classes/KinematicBody2D.xml2
-rw-r--r--doc/classes/KinematicBody3D.xml2
-rw-r--r--doc/classes/Light2D.xml2
-rw-r--r--doc/classes/Light3D.xml10
-rw-r--r--doc/classes/LightOccluder2D.xml2
-rw-r--r--doc/classes/LinkButton.xml1
-rw-r--r--doc/classes/MenuButton.xml1
-rw-r--r--doc/classes/Mesh.xml2
-rw-r--r--doc/classes/MeshInstance2D.xml2
-rw-r--r--doc/classes/MultiMesh.xml6
-rw-r--r--doc/classes/MultiMeshInstance3D.xml6
-rw-r--r--doc/classes/Mutex.xml2
-rw-r--r--doc/classes/NavigationMesh.xml10
-rw-r--r--doc/classes/NetworkedMultiplayerPeer.xml2
-rw-r--r--doc/classes/Node.xml7
-rw-r--r--doc/classes/Node2D.xml2
-rw-r--r--doc/classes/Node3D.xml2
-rw-r--r--doc/classes/OS.xml7
-rw-r--r--doc/classes/Object.xml9
-rw-r--r--doc/classes/OmniLight3D.xml2
-rw-r--r--doc/classes/OptionButton.xml3
-rw-r--r--doc/classes/PCKPacker.xml6
-rw-r--r--doc/classes/PackedByteArray.xml31
-rw-r--r--doc/classes/ParticlesMaterial.xml27
-rw-r--r--doc/classes/PhysicsBody2D.xml6
-rw-r--r--doc/classes/PhysicsBody3D.xml6
-rw-r--r--doc/classes/PhysicsDirectBodyState2D.xml2
-rw-r--r--doc/classes/PhysicsDirectSpaceState2D.xml2
-rw-r--r--doc/classes/PhysicsDirectSpaceState3D.xml2
-rw-r--r--doc/classes/PhysicsShapeQueryParameters2D.xml2
-rw-r--r--doc/classes/PhysicsShapeQueryParameters3D.xml2
-rw-r--r--doc/classes/Plane.xml2
-rw-r--r--doc/classes/PopupMenu.xml34
-rw-r--r--doc/classes/ProjectSettings.xml23
-rw-r--r--doc/classes/Quat.xml2
-rw-r--r--doc/classes/RayCast2D.xml14
-rw-r--r--doc/classes/RayCast3D.xml14
-rw-r--r--doc/classes/Rect2.xml5
-rw-r--r--doc/classes/Rect2i.xml4
-rw-r--r--doc/classes/ReflectionProbe.xml2
-rw-r--r--doc/classes/RenderingServer.xml51
-rw-r--r--doc/classes/RichTextEffect.xml4
-rw-r--r--doc/classes/RichTextLabel.xml5
-rw-r--r--doc/classes/RigidBody2D.xml1
-rw-r--r--doc/classes/RigidBody3D.xml3
-rw-r--r--doc/classes/SceneTree.xml4
-rw-r--r--doc/classes/Script.xml2
-rw-r--r--doc/classes/ScriptEditor.xml1
-rw-r--r--doc/classes/Semaphore.xml2
-rw-r--r--doc/classes/Shader.xml4
-rw-r--r--doc/classes/ShaderMaterial.xml2
-rw-r--r--doc/classes/Shape2D.xml2
-rw-r--r--doc/classes/Shape3D.xml2
-rw-r--r--doc/classes/Shortcut.xml (renamed from doc/classes/ShortCut.xml)2
-rw-r--r--doc/classes/Skeleton2D.xml2
-rw-r--r--doc/classes/SoftBody3D.xml6
-rw-r--r--doc/classes/SpotLight3D.xml2
-rw-r--r--doc/classes/SpringArm3D.xml2
-rw-r--r--doc/classes/Sprite2D.xml4
-rw-r--r--doc/classes/Sprite3D.xml7
-rw-r--r--doc/classes/SpriteBase3D.xml12
-rw-r--r--doc/classes/SpriteFrames.xml3
-rw-r--r--doc/classes/StreamPeerSSL.xml2
-rw-r--r--doc/classes/StreamTexture3D.xml25
-rw-r--r--doc/classes/String.xml51
-rw-r--r--doc/classes/SubViewport.xml1
-rw-r--r--doc/classes/Tabs.xml7
-rw-r--r--doc/classes/TextEdit.xml310
-rw-r--r--doc/classes/Texture2D.xml2
-rw-r--r--doc/classes/Texture3D.xml49
-rw-r--r--doc/classes/TextureButton.xml1
-rw-r--r--doc/classes/Theme.xml2
-rw-r--r--doc/classes/Thread.xml1
-rw-r--r--doc/classes/TileMap.xml8
-rw-r--r--doc/classes/Transform.xml6
-rw-r--r--doc/classes/Transform2D.xml2
-rw-r--r--doc/classes/Translation.xml4
-rw-r--r--doc/classes/TranslationServer.xml4
-rw-r--r--doc/classes/Variant.xml2
-rw-r--r--doc/classes/Vector2.xml4
-rw-r--r--doc/classes/Vector2i.xml2
-rw-r--r--doc/classes/Vector3.xml4
-rw-r--r--doc/classes/Vector3i.xml2
-rw-r--r--doc/classes/VideoPlayer.xml2
-rw-r--r--doc/classes/Viewport.xml4
-rw-r--r--doc/classes/VisualInstance3D.xml4
-rw-r--r--doc/classes/VisualShader.xml9
-rw-r--r--doc/classes/VisualShaderNode.xml8
-rw-r--r--doc/classes/VisualShaderNodeCustom.xml6
-rw-r--r--doc/classes/VisualShaderNodeInput.xml2
-rw-r--r--doc/classes/VisualShaderNodeTexture.xml2
-rw-r--r--doc/classes/VisualShaderNodeTexture3D.xml20
-rw-r--r--doc/classes/VisualShaderNodeTexture3DUniform.xml15
-rw-r--r--doc/classes/World2D.xml2
-rw-r--r--doc/classes/World3D.xml2
-rw-r--r--doc/classes/WorldEnvironment.xml2
-rw-r--r--doc/classes/XRCamera3D.xml2
-rw-r--r--doc/classes/XRController3D.xml2
-rw-r--r--doc/classes/XRInterface.xml2
-rw-r--r--doc/classes/XROrigin3D.xml2
-rw-r--r--doc/classes/XRPositionalTracker.xml2
-rw-r--r--doc/classes/XRServer.xml2
-rw-r--r--doc/classes/bool.xml83
-rwxr-xr-xdoc/tools/makerst.py2
-rw-r--r--doc/translations/classes.pot2
-rw-r--r--drivers/SCsub9
-rw-r--r--drivers/alsa/audio_driver_alsa.h8
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h7
-rw-r--r--drivers/dummy/rasterizer_dummy.h949
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h8
-rw-r--r--drivers/unix/file_access_unix.cpp2
-rw-r--r--drivers/unix/os_unix.cpp39
-rw-r--r--drivers/unix/thread_posix.cpp10
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp20
-rw-r--r--drivers/windows/dir_access_windows.cpp132
-rw-r--r--drivers/windows/file_access_windows.cpp57
-rw-r--r--editor/code_editor.cpp199
-rw-r--r--editor/code_editor.h16
-rw-r--r--editor/connections_dialog.cpp5
-rw-r--r--editor/editor_about.cpp5
-rw-r--r--editor/editor_audio_buses.h2
-rw-r--r--editor/editor_builders.py1
-rw-r--r--editor/editor_data.cpp10
-rw-r--r--editor/editor_export.cpp276
-rw-r--r--editor/editor_export.h26
-rw-r--r--editor/editor_feature_profile.cpp19
-rw-r--r--editor/editor_feature_profile.h2
-rw-r--r--editor/editor_help.cpp16
-rw-r--r--editor/editor_log.cpp10
-rw-r--r--editor/editor_node.cpp29
-rw-r--r--editor/editor_run.cpp4
-rw-r--r--editor/editor_run_native.cpp2
-rw-r--r--editor/editor_sectioned_inspector.cpp2
-rw-r--r--editor/editor_settings.cpp37
-rw-r--r--editor/editor_settings.h10
-rw-r--r--editor/editor_spin_slider.cpp7
-rw-r--r--editor/editor_themes.cpp27
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/find_in_files.cpp4
-rw-r--r--editor/icons/AutoKey.svg2
-rw-r--r--editor/icons/Shortcut.svg (renamed from editor/icons/ShortCut.svg)0
-rw-r--r--editor/import/resource_importer_layered_texture.cpp113
-rw-r--r--editor/import/resource_importer_layered_texture.h4
-rw-r--r--editor/input_map_editor.cpp2
-rw-r--r--editor/node_3d_editor_gizmos.cpp2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp11
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h10
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp32
-rw-r--r--editor/plugins/editor_debugger_plugin.h2
-rw-r--r--editor/plugins/editor_preview_plugins.cpp4
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp1
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp171
-rw-r--r--editor/plugins/node_3d_editor_plugin.h6
-rw-r--r--editor/plugins/script_editor_plugin.cpp7
-rw-r--r--editor/plugins/script_editor_plugin.h2
-rw-r--r--editor/plugins/script_text_editor.cpp243
-rw-r--r--editor/plugins/script_text_editor.h13
-rw-r--r--editor/plugins/shader_editor_plugin.cpp139
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp7
-rw-r--r--editor/plugins/text_editor.cpp45
-rw-r--r--editor/plugins/text_editor.h2
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp213
-rw-r--r--editor/plugins/texture_3d_editor_plugin.h93
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_plugin.cpp4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp5
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp16
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1797
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h108
-rw-r--r--editor/project_export.cpp125
-rw-r--r--editor/project_export.h11
-rw-r--r--editor/project_manager.cpp575
-rw-r--r--editor/project_manager.h78
-rw-r--r--editor/project_settings_editor.cpp1
-rw-r--r--editor/scene_tree_dock.cpp10
-rw-r--r--editor/scene_tree_dock.h3
-rw-r--r--editor/scene_tree_editor.cpp3
-rw-r--r--editor/script_create_dialog.cpp10
-rw-r--r--editor/settings_config_dialog.cpp8
-rw-r--r--editor/translations/af.po110
-rw-r--r--editor/translations/ar.po943
-rw-r--r--editor/translations/bg.po157
-rw-r--r--editor/translations/bn.po135
-rw-r--r--editor/translations/ca.po137
-rw-r--r--editor/translations/cs.po183
-rw-r--r--editor/translations/da.po136
-rw-r--r--editor/translations/de.po195
-rw-r--r--editor/translations/editor.pot101
-rw-r--r--editor/translations/el.po138
-rw-r--r--editor/translations/eo.po130
-rw-r--r--editor/translations/es.po145
-rw-r--r--editor/translations/es_AR.po138
-rw-r--r--editor/translations/et.po362
-rw-r--r--editor/translations/eu.po104
-rwxr-xr-xeditor/translations/extract.py139
-rw-r--r--editor/translations/fa.po183
-rw-r--r--editor/translations/fi.po140
-rw-r--r--editor/translations/fil.po141
-rw-r--r--editor/translations/fr.po149
-rw-r--r--editor/translations/ga.po102
-rw-r--r--editor/translations/he.po1188
-rw-r--r--editor/translations/hi.po133
-rw-r--r--editor/translations/hr.po105
-rw-r--r--editor/translations/hu.po2735
-rw-r--r--editor/translations/id.po160
-rw-r--r--editor/translations/is.po101
-rw-r--r--editor/translations/it.po183
-rw-r--r--editor/translations/ja.po158
-rw-r--r--editor/translations/ka.po105
-rw-r--r--editor/translations/ko.po140
-rw-r--r--editor/translations/lt.po134
-rw-r--r--editor/translations/lv.po105
-rw-r--r--editor/translations/mi.po101
-rw-r--r--editor/translations/ml.po101
-rw-r--r--editor/translations/mr.po101
-rw-r--r--editor/translations/ms.po1288
-rw-r--r--editor/translations/nb.po138
-rw-r--r--editor/translations/nl.po158
-rw-r--r--editor/translations/or.po101
-rw-r--r--editor/translations/pl.po202
-rw-r--r--editor/translations/pr.po110
-rw-r--r--editor/translations/pt.po (renamed from editor/translations/pt_PT.po)321
-rw-r--r--editor/translations/pt_BR.po145
-rw-r--r--editor/translations/ro.po136
-rw-r--r--editor/translations/ru.po177
-rw-r--r--editor/translations/si.po101
-rw-r--r--editor/translations/sk.po1048
-rw-r--r--editor/translations/sl.po136
-rw-r--r--editor/translations/sq.po136
-rw-r--r--editor/translations/sr_Cyrl.po134
-rw-r--r--editor/translations/sr_Latn.po101
-rw-r--r--editor/translations/sv.po133
-rw-r--r--editor/translations/ta.po123
-rw-r--r--editor/translations/te.po114
-rw-r--r--editor/translations/th.po159
-rw-r--r--editor/translations/tr.po171
-rw-r--r--editor/translations/uk.po140
-rw-r--r--editor/translations/ur_PK.po106
-rw-r--r--editor/translations/vi.po123
-rw-r--r--editor/translations/zh_CN.po182
-rw-r--r--editor/translations/zh_HK.po116
-rw-r--r--editor/translations/zh_TW.po140
-rw-r--r--glsl_builders.py10
-rw-r--r--main/main.cpp34
-rw-r--r--main/main_builders.py1
-rw-r--r--main/splash_editor.pngbin28059 -> 25801 bytes
-rw-r--r--methods.py92
-rw-r--r--misc/dist/html/fixed-size.html1
-rw-r--r--misc/dist/html/full-size.html29
-rw-r--r--modules/arkit/register_types.h5
-rw-r--r--modules/basis_universal/texture_basisu.h5
-rw-r--r--modules/bullet/bullet_types_converter.cpp59
-rw-r--r--modules/bullet/rigid_body_bullet.cpp4
-rw-r--r--modules/bullet/shape_bullet.cpp2
-rw-r--r--modules/camera/register_types.h5
-rw-r--r--modules/csg/doc_classes/CSGShape3D.xml4
-rw-r--r--modules/cvtt/register_types.h8
-rw-r--r--modules/denoise/register_types.h5
-rw-r--r--modules/denoise/resource_to_cpp.py2
-rw-r--r--modules/enet/doc_classes/NetworkedMultiplayerENet.xml4
-rw-r--r--modules/gdnative/doc_classes/GDNativeLibrary.xml4
-rw-r--r--modules/gdnative/gdnative/string.cpp649
-rw-r--r--modules/gdnative/gdnative_api.json390
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp1
-rw-r--r--modules/gdnative/include/gdnative/string.h158
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp4
-rw-r--r--modules/gdnative/tests/test_string.h1980
-rw-r--r--modules/gdscript/SCsub4
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml79
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml2
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp38
-rw-r--r--modules/gdscript/gdscript.cpp32
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp168
-rw-r--r--modules/gdscript/gdscript_analyzer.h6
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp736
-rw-r--r--modules/gdscript/gdscript_byte_codegen.h277
-rw-r--r--modules/gdscript/gdscript_cache.cpp10
-rw-r--r--modules/gdscript/gdscript_codegen.h160
-rw-r--r--modules/gdscript/gdscript_compiler.cpp2667
-rw-r--r--modules/gdscript/gdscript_compiler.h160
-rw-r--r--modules/gdscript/gdscript_function.cpp523
-rw-r--r--modules/gdscript/gdscript_function.h16
-rw-r--r--modules/gdscript/gdscript_functions.cpp2
-rw-r--r--modules/gdscript/gdscript_parser.cpp33
-rw-r--r--modules/gdscript/gdscript_parser.h2
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp82
-rw-r--r--modules/gdscript/gdscript_tokenizer.h22
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp6
-rw-r--r--modules/gdscript/register_types.cpp30
-rw-r--r--modules/gdscript/tests/test_gdscript.cpp (renamed from tests/test_gdscript.cpp)88
-rw-r--r--modules/gdscript/tests/test_gdscript.h (renamed from tests/test_gdscript.h)5
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml4
-rw-r--r--modules/jsonrpc/jsonrpc.cpp4
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp21
-rw-r--r--modules/mono/build_scripts/mono_configure.py4
-rw-r--r--modules/mono/build_scripts/mono_reg_utils.py10
-rw-r--r--modules/mono/build_scripts/solution_builder.py3
-rw-r--r--modules/mono/config.py10
-rw-r--r--modules/mono/doc_classes/CSharpScript.xml2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs25
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs17
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs2
-rwxr-xr-xmodules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs21
-rw-r--r--modules/mono/editor/godotsharp_export.cpp41
-rw-r--r--modules/mono/editor/script_class_parser.cpp8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs34
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs133
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs50
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs13
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs28
-rw-r--r--modules/mono/glue/collections_glue.cpp23
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp10
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp25
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp38
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h26
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h21
-rw-r--r--modules/mono/register_types.h5
-rw-r--r--modules/mono/utils/macros.h2
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp8
-rw-r--r--modules/mono/utils/path_utils.cpp26
-rw-r--r--modules/mono/utils/string_utils.cpp6
-rw-r--r--modules/pvr/texture_loader_pvr.cpp8
-rw-r--r--modules/regex/regex.cpp229
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp8
-rw-r--r--modules/theora/doc_classes/VideoStreamTheora.xml5
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp158
-rw-r--r--modules/visual_script/doc_classes/VisualScript.xml2
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp22
-rw-r--r--modules/visual_script/visual_script_editor.h3
-rw-r--r--modules/visual_script/visual_script_expression.cpp14
-rw-r--r--modules/visual_script/visual_script_nodes.cpp52
-rw-r--r--modules/webm/doc_classes/VideoStreamWebm.xml3
-rw-r--r--modules/webrtc/doc_classes/WebRTCPeerConnection.xml2
-rw-r--r--modules/webrtc/webrtc_data_channel_gdnative.h8
-rw-r--r--modules/webrtc/webrtc_data_channel_js.h8
-rw-r--r--modules/webrtc/webrtc_multiplayer.h2
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.h8
-rw-r--r--platform/android/export/export.cpp14
-rw-r--r--platform/android/export/gradle_export_util.h2
-rw-r--r--platform/android/java/lib/res/values/dimens.xml4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java24
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java6
-rw-r--r--platform/iphone/display_server_iphone.mm4
-rw-r--r--platform/iphone/export/export.cpp9
-rw-r--r--platform/iphone/godot_view_gesture_recognizer.h2
-rw-r--r--platform/iphone/in_app_store.mm2
-rw-r--r--platform/iphone/ios.mm2
-rw-r--r--platform/iphone/os_iphone.mm4
-rw-r--r--platform/javascript/SCsub2
-rw-r--r--platform/javascript/audio_driver_javascript.h22
-rw-r--r--platform/javascript/display_server_javascript.cpp44
-rw-r--r--platform/javascript/display_server_javascript.h104
-rw-r--r--platform/javascript/engine/engine.js28
-rw-r--r--platform/javascript/export/export.cpp2
-rw-r--r--platform/javascript/javascript_main.cpp77
-rw-r--r--platform/javascript/native/utils.js75
-rw-r--r--platform/javascript/os_javascript.cpp71
-rw-r--r--platform/javascript/os_javascript.h49
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp4
-rw-r--r--platform/linuxbsd/detect.py6
-rw-r--r--platform/linuxbsd/display_server_x11.cpp384
-rw-r--r--platform/linuxbsd/display_server_x11.h8
-rw-r--r--platform/linuxbsd/platform_config.h12
-rw-r--r--platform/osx/crash_handler_osx.mm4
-rw-r--r--platform/osx/detect.py1
-rw-r--r--platform/osx/display_server_osx.h4
-rw-r--r--platform/osx/display_server_osx.mm47
-rw-r--r--platform/osx/export/export.cpp2
-rw-r--r--platform/server/platform_config.h13
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/uwp/export/export.cpp2
-rw-r--r--platform/uwp/os_uwp.cpp8
-rw-r--r--platform/windows/SCsub6
-rw-r--r--platform/windows/crash_handler_windows.cpp2
-rw-r--r--platform/windows/detect.py22
-rw-r--r--platform/windows/display_server_windows.cpp120
-rw-r--r--platform/windows/display_server_windows.h6
-rw-r--r--platform/windows/os_windows.cpp61
-rw-r--r--platform_methods.py2
-rw-r--r--scene/2d/cpu_particles_2d.cpp2
-rw-r--r--scene/2d/parallax_background.cpp2
-rw-r--r--scene/2d/ray_cast_2d.cpp24
-rw-r--r--scene/2d/ray_cast_2d.h6
-rw-r--r--scene/2d/sprite_2d.cpp2
-rw-r--r--scene/2d/tile_map.cpp25
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/3d/collision_shape_3d.cpp23
-rw-r--r--scene/3d/collision_shape_3d.h2
-rw-r--r--scene/3d/cpu_particles_3d.cpp2
-rw-r--r--scene/3d/gpu_particles_3d.cpp52
-rw-r--r--scene/3d/gpu_particles_3d.h17
-rw-r--r--scene/3d/ray_cast_3d.cpp20
-rw-r--r--scene/3d/ray_cast_3d.h6
-rw-r--r--scene/3d/soft_body_3d.cpp2
-rw-r--r--scene/3d/soft_body_3d.h2
-rw-r--r--scene/3d/sprite_3d.cpp2
-rw-r--r--scene/gui/base_button.cpp10
-rw-r--r--scene/gui/base_button.h6
-rw-r--r--scene/gui/code_edit.cpp444
-rw-r--r--scene/gui/code_edit.h135
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/graph_edit.cpp1
-rw-r--r--scene/gui/label.cpp30
-rw-r--r--scene/gui/line_edit.cpp17
-rw-r--r--scene/gui/popup.cpp90
-rw-r--r--scene/gui/popup.h9
-rw-r--r--scene/gui/popup_menu.cpp401
-rw-r--r--scene/gui/popup_menu.h45
-rw-r--r--scene/gui/rich_text_effect.h4
-rw-r--r--scene/gui/rich_text_label.cpp18
-rw-r--r--scene/gui/rich_text_label.h1
-rw-r--r--scene/gui/shortcut.cpp24
-rw-r--r--scene/gui/shortcut.h6
-rw-r--r--scene/gui/tabs.cpp9
-rw-r--r--scene/gui/tabs.h2
-rw-r--r--scene/gui/text_edit.cpp934
-rw-r--r--scene/gui/text_edit.h293
-rw-r--r--scene/gui/tree.cpp18
-rw-r--r--scene/main/canvas_item.cpp6
-rw-r--r--scene/main/canvas_item.h4
-rw-r--r--scene/main/http_request.cpp114
-rw-r--r--scene/main/http_request.h13
-rw-r--r--scene/main/node.cpp7
-rw-r--r--scene/main/scene_tree.h6
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/main/window.cpp5
-rw-r--r--scene/register_scene_types.cpp17
-rw-r--r--scene/resources/default_theme/bookmark.pngbin0 -> 160 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp51
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/dynamic_font.cpp16
-rw-r--r--scene/resources/dynamic_font.h16
-rw-r--r--scene/resources/font.cpp26
-rw-r--r--scene/resources/font.h26
-rw-r--r--scene/resources/gradient.cpp2
-rw-r--r--scene/resources/mesh.h1
-rw-r--r--scene/resources/mesh_library.h6
-rw-r--r--scene/resources/packed_scene.cpp4
-rw-r--r--scene/resources/particles_material.cpp285
-rw-r--r--scene/resources/particles_material.h65
-rw-r--r--scene/resources/physics_material.cpp4
-rw-r--r--scene/resources/shader.cpp2
-rw-r--r--scene/resources/style_box.cpp3
-rw-r--r--scene/resources/syntax_highlighter.cpp43
-rw-r--r--scene/resources/syntax_highlighter.h2
-rw-r--r--scene/resources/texture.cpp304
-rw-r--r--scene/resources/texture.h119
-rw-r--r--scene/resources/tile_set.cpp4
-rw-r--r--scene/resources/visual_shader.cpp242
-rw-r--r--scene/resources/visual_shader.h48
-rw-r--r--scene/resources/visual_shader_nodes.cpp233
-rw-r--r--scene/resources/visual_shader_nodes.h159
-rw-r--r--servers/display_server.cpp9
-rw-r--r--servers/display_server.h3
-rw-r--r--servers/physics_2d/body_2d_sw.cpp2
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp4
-rw-r--r--servers/physics_2d/physics_server_2d_sw.cpp4
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.h4
-rw-r--r--servers/physics_server_2d.h2
-rw-r--r--servers/physics_server_3d.h2
-rw-r--r--servers/rendering/rasterizer.h13
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp95
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.h29
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp77
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp9
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h6
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp1268
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h365
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.cpp14
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.h3
-rw-r--r--servers/rendering/rasterizer_rd/shaders/SCsub3
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas.glsl2
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl42
-rw-r--r--servers/rendering/rasterizer_rd/shaders/particles.glsl394
-rw-r--r--servers/rendering/rasterizer_rd/shaders/particles_copy.glsl82
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl8
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl2
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl2
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl4
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl8
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sort.glsl203
-rw-r--r--servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl2
-rw-r--r--servers/rendering/rendering_server_canvas.cpp14
-rw-r--r--servers/rendering/rendering_server_canvas.h4
-rw-r--r--servers/rendering/rendering_server_raster.h17
-rw-r--r--servers/rendering/rendering_server_scene.cpp1
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h10
-rw-r--r--servers/rendering/shader_language.cpp275
-rw-r--r--servers/rendering/shader_language.h31
-rw-r--r--servers/rendering/shader_types.cpp52
-rw-r--r--servers/rendering_server.cpp6
-rw-r--r--servers/rendering_server.h26
-rw-r--r--servers/text_server.h0
-rw-r--r--tests/SCsub5
-rw-r--r--tests/test_color.h8
-rw-r--r--tests/test_expression.h445
-rw-r--r--tests/test_list.h279
-rw-r--r--tests/test_macros.cpp42
-rw-r--r--tests/test_macros.h16
-rw-r--r--tests/test_main.cpp55
-rw-r--r--tests/test_math.cpp8
-rw-r--r--tests/test_shader_lang.cpp2
-rw-r--r--tests/test_string.h570
-rw-r--r--thirdparty/README.md6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aes.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aesni.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/arc4.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aria.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1write.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/base64.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bignum.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/blowfish.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bn_mul.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/camellia.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ccm.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/certs.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/chacha20.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/chachapoly.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/check_config.h14
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cipher.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cipher_internal.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cmac.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/compat-1.3.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/config.h40
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ctr_drbg.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/debug.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/des.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/dhm.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdh.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdsa.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecjpake.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp_internal.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/entropy.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/entropy_poll.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/error.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/gcm.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/havege.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hkdf.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hmac_drbg.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md.h4
-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/md_internal.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/net.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/net_sockets.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/nist_kw.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/oid.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/padlock.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pem.h36
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pk.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pk_internal.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs11.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs12.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs5.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_time.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_util.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/poly1305.h4
-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/rsa_internal.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.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cache.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cookie.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_internal.h89
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ticket.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/threading.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/timing.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h12
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crl.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crt.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_csr.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/xtea.h4
-rw-r--r--thirdparty/mbedtls/library/aes.c4
-rw-r--r--thirdparty/mbedtls/library/aesni.c4
-rw-r--r--thirdparty/mbedtls/library/arc4.c4
-rw-r--r--thirdparty/mbedtls/library/aria.c4
-rw-r--r--thirdparty/mbedtls/library/asn1parse.c4
-rw-r--r--thirdparty/mbedtls/library/asn1write.c4
-rw-r--r--thirdparty/mbedtls/library/base64.c4
-rw-r--r--thirdparty/mbedtls/library/bignum.c4
-rw-r--r--thirdparty/mbedtls/library/blowfish.c4
-rw-r--r--thirdparty/mbedtls/library/camellia.c4
-rw-r--r--thirdparty/mbedtls/library/ccm.c4
-rw-r--r--thirdparty/mbedtls/library/certs.c4
-rw-r--r--thirdparty/mbedtls/library/chacha20.c4
-rw-r--r--thirdparty/mbedtls/library/chachapoly.c4
-rw-r--r--thirdparty/mbedtls/library/cipher.c4
-rw-r--r--thirdparty/mbedtls/library/cipher_wrap.c4
-rw-r--r--thirdparty/mbedtls/library/cmac.c4
-rw-r--r--thirdparty/mbedtls/library/ctr_drbg.c4
-rw-r--r--thirdparty/mbedtls/library/debug.c4
-rw-r--r--thirdparty/mbedtls/library/des.c4
-rw-r--r--thirdparty/mbedtls/library/dhm.c62
-rw-r--r--thirdparty/mbedtls/library/ecdh.c4
-rw-r--r--thirdparty/mbedtls/library/ecdsa.c4
-rw-r--r--thirdparty/mbedtls/library/ecjpake.c4
-rw-r--r--thirdparty/mbedtls/library/ecp.c4
-rw-r--r--thirdparty/mbedtls/library/ecp_curves.c4
-rw-r--r--thirdparty/mbedtls/library/entropy.c4
-rw-r--r--thirdparty/mbedtls/library/entropy_poll.c4
-rw-r--r--thirdparty/mbedtls/library/error.c4
-rw-r--r--thirdparty/mbedtls/library/gcm.c4
-rw-r--r--thirdparty/mbedtls/library/havege.c4
-rw-r--r--thirdparty/mbedtls/library/hkdf.c4
-rw-r--r--thirdparty/mbedtls/library/hmac_drbg.c4
-rw-r--r--thirdparty/mbedtls/library/md.c4
-rw-r--r--thirdparty/mbedtls/library/md2.c4
-rw-r--r--thirdparty/mbedtls/library/md4.c4
-rw-r--r--thirdparty/mbedtls/library/md5.c4
-rw-r--r--thirdparty/mbedtls/library/md_wrap.c4
-rw-r--r--thirdparty/mbedtls/library/memory_buffer_alloc.c4
-rw-r--r--thirdparty/mbedtls/library/net_sockets.c13
-rw-r--r--thirdparty/mbedtls/library/nist_kw.c4
-rw-r--r--thirdparty/mbedtls/library/oid.c4
-rw-r--r--thirdparty/mbedtls/library/padlock.c4
-rw-r--r--thirdparty/mbedtls/library/pem.c4
-rw-r--r--thirdparty/mbedtls/library/pk.c4
-rw-r--r--thirdparty/mbedtls/library/pk_wrap.c4
-rw-r--r--thirdparty/mbedtls/library/pkcs11.c4
-rw-r--r--thirdparty/mbedtls/library/pkcs12.c4
-rw-r--r--thirdparty/mbedtls/library/pkcs5.c4
-rw-r--r--thirdparty/mbedtls/library/pkparse.c4
-rw-r--r--thirdparty/mbedtls/library/pkwrite.c4
-rw-r--r--thirdparty/mbedtls/library/platform.c4
-rw-r--r--thirdparty/mbedtls/library/platform_util.c4
-rw-r--r--thirdparty/mbedtls/library/poly1305.c4
-rw-r--r--thirdparty/mbedtls/library/ripemd160.c4
-rw-r--r--thirdparty/mbedtls/library/rsa.c46
-rw-r--r--thirdparty/mbedtls/library/rsa_internal.c4
-rw-r--r--thirdparty/mbedtls/library/sha1.c4
-rw-r--r--thirdparty/mbedtls/library/sha256.c4
-rw-r--r--thirdparty/mbedtls/library/sha512.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_cache.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_ciphersuites.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_cookie.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_srv.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_ticket.c4
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c307
-rw-r--r--thirdparty/mbedtls/library/threading.c4
-rw-r--r--thirdparty/mbedtls/library/timing.c4
-rw-r--r--thirdparty/mbedtls/library/version.c4
-rw-r--r--thirdparty/mbedtls/library/version_features.c10
-rw-r--r--thirdparty/mbedtls/library/x509.c4
-rw-r--r--thirdparty/mbedtls/library/x509_create.c4
-rw-r--r--thirdparty/mbedtls/library/x509_crl.c6
-rw-r--r--thirdparty/mbedtls/library/x509_crt.c7
-rw-r--r--thirdparty/mbedtls/library/x509_csr.c4
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c238
-rw-r--r--thirdparty/mbedtls/library/x509write_csr.c150
-rw-r--r--thirdparty/mbedtls/library/xtea.c4
-rw-r--r--thirdparty/tinyexr/tinyexr.cc6
-rw-r--r--thirdparty/tinyexr/tinyexr.h710
-rw-r--r--thirdparty/zstd/common/bitstream.h68
-rw-r--r--thirdparty/zstd/common/compiler.h22
-rw-r--r--thirdparty/zstd/common/cpu.h2
-rw-r--r--thirdparty/zstd/common/debug.c42
-rw-r--r--thirdparty/zstd/common/debug.h42
-rw-r--r--thirdparty/zstd/common/entropy_common.c46
-rw-r--r--thirdparty/zstd/common/error_private.c3
-rw-r--r--thirdparty/zstd/common/error_private.h8
-rw-r--r--thirdparty/zstd/common/fse.h42
-rw-r--r--thirdparty/zstd/common/fse_decompress.c49
-rw-r--r--thirdparty/zstd/common/huf.h48
-rw-r--r--thirdparty/zstd/common/mem.h2
-rw-r--r--thirdparty/zstd/common/pool.c2
-rw-r--r--thirdparty/zstd/common/pool.h4
-rw-r--r--thirdparty/zstd/common/threading.c7
-rw-r--r--thirdparty/zstd/common/threading.h7
-rw-r--r--thirdparty/zstd/common/xxhash.c48
-rw-r--r--thirdparty/zstd/common/xxhash.h42
-rw-r--r--thirdparty/zstd/common/zstd_common.c2
-rw-r--r--thirdparty/zstd/common/zstd_errors.h3
-rw-r--r--thirdparty/zstd/common/zstd_internal.h127
-rw-r--r--thirdparty/zstd/compress/fse_compress.c57
-rw-r--r--thirdparty/zstd/compress/hist.c50
-rw-r--r--thirdparty/zstd/compress/hist.h44
-rw-r--r--thirdparty/zstd/compress/huf_compress.c184
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c725
-rw-r--r--thirdparty/zstd/compress/zstd_compress_internal.h150
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.c16
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.h2
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.c44
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.h13
-rw-r--r--thirdparty/zstd/compress/zstd_compress_superblock.c845
-rw-r--r--thirdparty/zstd/compress/zstd_compress_superblock.h32
-rw-r--r--thirdparty/zstd/compress/zstd_cwksp.h16
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.c19
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.h4
-rw-r--r--thirdparty/zstd/compress/zstd_fast.c60
-rw-r--r--thirdparty/zstd/compress/zstd_fast.h4
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.c45
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.h2
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.c32
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.h9
-rw-r--r--thirdparty/zstd/compress/zstd_opt.c122
-rw-r--r--thirdparty/zstd/compress/zstd_opt.h2
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.c69
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.h4
-rw-r--r--thirdparty/zstd/decompress/huf_decompress.c138
-rw-r--r--thirdparty/zstd/decompress/zstd_ddict.c20
-rw-r--r--thirdparty/zstd/decompress/zstd_ddict.h4
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c412
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.c515
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.h6
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_internal.h22
-rw-r--r--thirdparty/zstd/zstd.h83
906 files changed, 35812 insertions, 18026 deletions
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index c2af0ac549..3fa759bb03 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -19,7 +19,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get install -qq dos2unix recode clang-format
- sudo pip3 install git+https://github.com/psf/black@master pygments
+ sudo pip3 install black==20.8b1 pygments
- name: File formatting checks (file_format.sh)
run: |
diff --git a/.gitignore b/.gitignore
index 6af581040c..8d1aad947d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -383,3 +383,6 @@ ruby.png
snow.png
updown.png
gcov.css
+
+# https://clangd.llvm.org/ cache folder
+.clangd/
diff --git a/.lgtm.yml b/.lgtm.yml
new file mode 100644
index 0000000000..e4841eaff4
--- /dev/null
+++ b/.lgtm.yml
@@ -0,0 +1,7 @@
+extraction:
+ cpp:
+ after_prepare:
+ - pip3 install scons
+ - PATH="/opt/work/.local/bin:$PATH"
+ index:
+ build_command: scons -j2
diff --git a/.mailmap b/.mailmap
index f2f69eb9da..c4e5de7e78 100644
--- a/.mailmap
+++ b/.mailmap
@@ -24,6 +24,7 @@ dankan1890 <mewuidev2@gmail.com>
Daniel J. Ramirez <djrmuv@gmail.com>
Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
Emmanuel Barroga <emmanuelbarroga@gmail.com>
+Eric M <itsjusteza@gmail.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
Fabian <supagu@gmail.com>
diff --git a/AUTHORS.md b/AUTHORS.md
index 40aa50f8b6..8ae19cfdf7 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -66,6 +66,7 @@ name is available.
Emmanuel Leblond (touilleMan)
Eoin O'Neill (Eoin-ONeill-Yokai)
Eric Lasota (elasota)
+ Eric M (EricEzaM)
Eric Rybicki (ericrybick)
Erik Selecký (rxlecky)
est31
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f8f8bd676..88c9e1a8a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -384,6 +384,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Ogg samples now have an icon in the editor, like WAV samples.
- Camera2D drag margins are now disabled by default.
- If porting a project from Godot 3.1 where drag margins were used, these must be enabled manually again.
+- The Camera2D Offset property now ignores the Limit property.
+ - To get the old behavior back, move the camera itself instead of changing the offset.
- `Camera.project_position()` now requires a second `depth` argument to determine the distance of the point from the camera.
- To get the old behavior back, pass the Camera's `near` property value as the second argument.
- `Skeleton.set_bone_global_pose()` was replaced by `Skeleton.set_bone_global_pose_override()`.
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 8ccdecd307..6122452b88 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -338,7 +338,7 @@ License: Expat
Files: ./thirdparty/tinyexr/
Comment: TinyEXR
-Copyright: 2014-2019, Syoyo Fujita
+Copyright: 2014-2020, Syoyo Fujita
2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
License: BSD-3-clause
@@ -380,7 +380,7 @@ License: Zlib
Files: ./thirdparty/zstd/
Comment: Zstandard
-Copyright: 2016-2019, Facebook, Inc.
+Copyright: 2016-2020, Facebook, Inc.
License: BSD-3-clause
diff --git a/DONORS.md b/DONORS.md
index 88e674f043..5728109135 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -14,7 +14,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Gamblify <https://www.gamblify.com>
Heroic Labs <https://heroiclabs.com>
- Interblock <http://interblockgaming.com>
## Gold sponsors
@@ -27,16 +26,17 @@ generous deed immortalized in the next stable release of Godot Engine.
## Bronze sponsors
Brandon Lamb
+ Garry Newman
## Mini sponsors
AD Ford
- Alan Beauchamp
albinaask
Alejandro Saucedo
alex brown
Andrew Dunai
Christian Baune
+ Christoffer Sundbom
Christopher Montesano
Darkhan Baimyrza
Darrin Massena
@@ -46,7 +46,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Edward Flick
Gamechuck
GameDev.net
- Grady
Hein-Pieter van Braam
Jacob McKenney
Jasper Brooks
@@ -78,7 +77,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Asher Glick
Austen McRae
Bernhard Werner
- beVR
Carlo Cabanilla
Chris Goddard
Christopher Case
@@ -93,8 +91,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Florian Rämisch
Forge
Gamejunkey
+ Grady
Jakub Grzesik
Javier Roman
+ Jeff Nyte
+ Joan Fons
Jon Woodward
Karl Werf
Klavdij Voncina
@@ -103,7 +104,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Maciej Pendolski
Manuele Finocchiaro
Markus Wiesner
+ Mason Bially
Matthew Hillier
+ m kaersten
Mohamed Ikbel Boulabiar
Monster Vial
Officine Pixel S.n.c.
@@ -114,10 +117,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Rob Messick
Roland Fredenhagen
Ronan Zeegers
- Ryan Badour
Sandro Jenny
Sarksus
- Scott Wadden
+ Sean
Sergey
Sofox
Spicylewd
@@ -133,13 +135,16 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Nakonieczny
Adam Neumann
Alexander J Maynard
+ Alex de la Mare
Alexey Dyadchenko
Alex Khayrullin
alice gambrell
Andreas Funke
André Frélicot
Andrew Harris
+ Antoni Batchelli
aoshiwik
+ Arisaka Mayuki
Barugon
Can Eris
Carlos de Sousa Marques
@@ -148,7 +153,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Chelsea Hash
Chris Petrich
Chris Serino
- Christian Alexander Bjørklund Bøhler
Christian Leth Jeppesen
Cody Parker
Conrad Curry
@@ -164,19 +168,20 @@ generous deed immortalized in the next stable release of Godot Engine.
Felix Brückner
flesk
F S
+ Gabrielius Vaiškūnas
Gary Hulst
gavlig
GGGames.org
GiulianoB
+ Green Fox
Guilherme Felipe de C. G. da Silva
Heath Hayes
Hoai Nam Tran
Horváth Péter
Hu Hund
+ James Couzens
Jared
Jared White
- Jeff Nyte
- Joan Fons
Joel Fivat
Joel Höglund
John G Gentzel
@@ -186,26 +191,31 @@ generous deed immortalized in the next stable release of Godot Engine.
Joshua Flores
Joshua Lesperance
Juan Velandia
+ Judd
Julian Todd
Juraj Móza
+ JUSTIN CARROLL
Justo Delgado Baudí
Kelteseth
kickmaniac
kinfox
+ kuku
Lachie
Lain Ballard
Leo Fidel R Liban
luca duran
+ Luc-Frédéric Langis
MadScientistCarl
Marcelo Dornbusch Lopes
Marisa Clardy
Markus Fehr
Martin Eigel
+ Martin Kotz
+ Martin Soucek
Matt Eunson
Michael
Michael Dürwald
Mikado069
- m kaersten
MuffinManKen
Nick Abousselam
Oliver Dick
@@ -221,13 +231,13 @@ generous deed immortalized in the next stable release of Godot Engine.
pl
Ranoller
Raymond Harris
+ razmie
Ricardo Alcantara
Rob
Robert Willes
Rob McInroy
Rocknight Studios
Ronnie Ashlock
- Ryan
Ryan Wilson
Samuel Judd
Scott Pilet
@@ -235,9 +245,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Sean Robertson
Sébastien
Serban Serafimescu
+ Sergey Minakov
Shishir Tandale
SKison
- SleepCircle
spilldata
Steven Landow
Stoned Xander
@@ -245,13 +255,14 @@ generous deed immortalized in the next stable release of Godot Engine.
TheLevelOfDetail .
Thomas Bjarnelöf
Thomas Kurz
+ Tim Howard
Timothy Pulliam
Tobias Bocanegra
Trent Fehl
Valryia
VikFro
- Vincent Henderson
Vojtěch
+ voxelv
William Foster
Wojciech Chojnacki
Xavier PATRICELLI
@@ -264,6 +275,7 @@ generous deed immortalized in the next stable release of Godot Engine.
1D_Inc
Aaron
+ Aaron Passchier
Abraham Haskins
Acheron
Adam
@@ -275,9 +287,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Smeltzer
Adam Szymański
Adisibio
+ Agar3s - Giovanny Beltrán
Agustinus Arya
Aidan O'Flannagain
Aki Mimoto
+ Alan Beauchamp
Albin Jonasson Svärdsby
Alder Stefano
AleMax
@@ -290,6 +304,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Allen Schade
Andreas Krampitz
André Simões
+ Andre Stackhouse
andrew james morris
Andrew Mansuetti
Andrew Rosenwinkel
@@ -298,16 +313,18 @@ generous deed immortalized in the next stable release of Godot Engine.
Anthony Avina
AP Condomines
Arda Erol
- Arisaka Mayuki
Armin Preiml
Arseniy M
Arthur S. Muszynski
Ashley Claymore
Ashton Scott Snapp
+ Astier Mickael
Aubrey Falconer
B A
Balázs Batári
+ Balázs Kondákor
Bartosz Bielecki
+ Bekhoucha Danyl
Benedikt
Ben Vercammen
Bernd Jänichen
@@ -315,6 +332,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Black Block
Blair Allen
Bobby CC Wong
+ Borkzilla
Bram
brian
Brian mc gowan
@@ -322,6 +340,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Burney Waring
Caleb Gartner
Cameron Meyer
+ Carlos Cejudo
Carl van der Geest
Carwyn Edwards
Cas Brugman
@@ -329,14 +348,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Chad Steadman
Chris Brown
Chris Chapin
+ Chris Jagusch
+ Christian Clavet
Christian Winter
Christoffer Dahlblom
- Christoffer Sundbom
Christophe Gagnier
Christopher Schmitt
- Christoph Woinke
Clay Heaton
Cole Johnson
+ Conall O
Curt King
CzechBlueBear
Daniel De Macedo
@@ -344,8 +364,10 @@ generous deed immortalized in the next stable release of Godot Engine.
DanielMaximiano
Daniel Szarfman
Daniel Tebbutt
+ Danny Welch
Daren Scot Wilson
Dave Walker
+ David Bôle
David May
David Woodard
David Zanetti
@@ -377,7 +399,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Fekinox
Felix Bohmann
Flaredown
- Florian Richer
Forty Doubleu
Frank
FuDiggity
@@ -385,6 +406,7 @@ generous deed immortalized in the next stable release of Godot Engine.
gamedev by Celio
Gary Thomas
George Marques
+ Greg Lincoln
Greg Olson
GREGORY C FEIN
Greyson Richey
@@ -394,9 +416,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Guldoman
Gustavo Loureiro dos Reis
Hal A
+ helija
Heribert Hirth
Hunter Jones
Hylpher
+ Ian Williams
Iiari
iKlem
IndustrialRobot
@@ -406,9 +430,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Jaguar
Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
+ Jake Huxell
Jako Danar
James
James A F Manley
+ James Thomas
Jamiee H
Jamie Massey
Janders
@@ -429,6 +455,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jonatan R
Jonathan G
Jon Bonazza
+ Jon Oakes
Jon Sully
Jordy Goodridge
Jorge Antunes
@@ -437,12 +464,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Josh Mitchell
Joshua Southerland
Juanfran
- Judd
Julian Murgia
June Little
JungleRobba
Justin Calleja
Justin Hamilton
+ Justin Oaksford
Justin Spedding
KaDokta
Karel Němec
@@ -454,11 +481,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Kevin McPhillips
Kiri Jolly
Kjetil Haugland
+ Kristian Nygaard Jensen
KsyTek Games
Kuan Cheang
kycho
Kyle Appelgate
Kyuppin
+ Laurent CHEA
Laurent Tréguier
LEMMiNO
Leonardo Dimano
@@ -496,9 +525,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Mikayla
Mike Birkhead
Mike Cunningham
+ Mitchell J. Wagner
Molinghu
+ Molly Jameson
MoM
- Mored4u
Nathan Fish
Natrim
nee
@@ -520,25 +550,25 @@ generous deed immortalized in the next stable release of Godot Engine.
Oleg Reva
Olivier
Omar Delarosa
+ Orinxlm
Oscar Domingo
Oscar Norlander
- Pan Ip
Parinya Teerakasemsuk
Patrick Dully
Patrick Nafarrete
Paul Gieske
Paul Mason
Paweł Kowal
+ Paweł Łyczkowski
Pedro Assuncao
Penguin
- Peter
Philip Cohoe
Pierre-Nicolas Tollitte
Piotr Góral
Point08
Preethi Vaidyanathan
+ Price Comstock
pwab
- Rad Cat
Rafa Laguna
Remi Rampin
Rémi Verschelde
@@ -547,6 +577,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Richard Ivánek
Robert Farr (Larington)
Robert Larnach
+ Rob Ruana
Roger Smith
Roland Rząsa
Roman Tinkov
@@ -558,6 +589,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Sam Caulfield
Sam Edson
Samuele Zolfanelli
+ sayaks
Scott D. Yelich
Scott Longley
ScottMakesGames
@@ -574,6 +606,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Simon Schoenenberger
Simon Wenner
Sintinium
+ Skalli
smbe19
smo1704
soft circles
@@ -581,9 +614,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Stefano Caronia
Steve Cloete
Svenne Krap
+ tadashi endo
Tannen Helmers
Terry
tezuvholovdr
+ Theodore Lindsey
TheVoiceInMyHead
thomas
Thomas Bechtold
@@ -591,6 +626,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Kelly
Tim Drumheller
Tim Erskine
+ Tim Gleason
Timothy B. MacDonald
Tobbun
Tobias Bradtke
@@ -622,10 +658,16 @@ generous deed immortalized in the next stable release of Godot Engine.
werner mendizabal
Wiley Thompson
Will
+ William Edwards
+ William F Siqueira
+ William Hogben
+ Windvis
Wyatt Goodin
+ x1212
Yegor Smirnov
YiYin Gu
Yuri Sizov
+ Zak Stephens
Zgegnesh Hemomancer
ΒΑΣΙΛΗΣ ΓΕΩΡΓΑΚΟΠΟΥΛΟΣ
郝晨煜
diff --git a/README.md b/README.md
index ad0fe3079c..1f2aa00f08 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,6 @@ provided by the community, such as text and video tutorials, demos, etc.
Consult the [community channels](https://godotengine.org/community)
for more information.
-[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
diff --git a/SConstruct b/SConstruct
index 64a4c48eff..e38e0dc231 100644
--- a/SConstruct
+++ b/SConstruct
@@ -13,8 +13,6 @@ from collections import OrderedDict
# Local
import methods
import glsl_builders
-import version
-from platform_methods import run_in_subprocess
# Scan possible build platforms
@@ -322,31 +320,6 @@ if selected_platform in platform_list:
if env["tools"]:
env["tests"] = True
- if env["vsproj"]:
- env.vs_incs = []
- env.vs_srcs = []
-
- def AddToVSProject(sources):
- for x in sources:
- if type(x) == type(""):
- fname = env.File(x).path
- else:
- fname = env.File(x)[0].path
- pieces = fname.split(".")
- if len(pieces) > 0:
- basename = pieces[0]
- basename = basename.replace("\\\\", "/")
- if os.path.isfile(basename + ".h"):
- env.vs_incs = env.vs_incs + [basename + ".h"]
- elif os.path.isfile(basename + ".hpp"):
- env.vs_incs = env.vs_incs + [basename + ".hpp"]
- if os.path.isfile(basename + ".c"):
- env.vs_srcs = env.vs_srcs + [basename + ".c"]
- elif os.path.isfile(basename + ".cpp"):
- env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
-
- env.AddToVSProject = AddToVSProject
-
env.extra_suffix = ""
if env["extra_suffix"] != "":
@@ -648,6 +621,10 @@ if selected_platform in platform_list:
CacheDir(scons_cache_path)
print("Scons cache enabled... (path: '" + scons_cache_path + "')")
+ if env["vsproj"]:
+ env.vs_incs = []
+ env.vs_srcs = []
+
Export("env")
# Build subdirs, the build order is dependent on link order.
diff --git a/core/SCsub b/core/SCsub
index 40ee78d3ea..59fe63b4b3 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -4,7 +4,6 @@ Import("env")
import core_builders
import make_binders
-from platform_methods import run_in_subprocess
env.core_sources = []
@@ -122,6 +121,7 @@ if env["builtin_zstd"]:
"compress/zstdmt_compress.c",
"compress/zstd_compress_literals.c",
"compress/zstd_compress_sequences.c",
+ "compress/zstd_compress_superblock.c",
"decompress/huf_decompress.c",
"decompress/zstd_ddict.c",
"decompress/zstd_decompress_block.c",
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 489ff762c9..c68222c767 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -519,10 +519,6 @@ uint64_t _OS::get_ticks_usec() const {
return OS::get_singleton()->get_ticks_usec();
}
-uint32_t _OS::get_splash_tick_msec() const {
- return OS::get_singleton()->get_splash_tick_msec();
-}
-
bool _OS::can_use_threads() const {
return OS::get_singleton()->can_use_threads();
}
@@ -730,7 +726,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec);
ClassDB::bind_method(D_METHOD("get_ticks_msec"), &_OS::get_ticks_msec);
ClassDB::bind_method(D_METHOD("get_ticks_usec"), &_OS::get_ticks_usec);
- ClassDB::bind_method(D_METHOD("get_splash_tick_msec"), &_OS::get_splash_tick_msec);
ClassDB::bind_method(D_METHOD("get_locale"), &_OS::get_locale);
ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index a59fcda60c..5c9520d7fe 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -208,7 +208,6 @@ public:
void delay_msec(uint32_t p_msec) const;
uint32_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
- uint32_t get_splash_tick_msec() const;
bool can_use_threads() const;
diff --git a/core/color.cpp b/core/color.cpp
index 27a2d0af5c..c61ee0e64a 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -261,33 +261,21 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) {
return Color(rd, gd, bd, 1.0f);
}
-static float _parse_col(const String &p_str, int p_ofs) {
- int ig = 0;
-
- for (int i = 0; i < 2; i++) {
- int c = p_str[i + p_ofs];
- int v = 0;
-
- if (c >= '0' && c <= '9') {
- v = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- v = c - 'a';
- v += 10;
- } else if (c >= 'A' && c <= 'F') {
- v = c - 'A';
- v += 10;
- } else {
- return -1;
- }
-
- if (i == 0) {
- ig += v * 16;
- } else {
- ig += v;
- }
+static int _parse_col4(const String &p_str, int p_ofs) {
+ char character = p_str[p_ofs];
+
+ if (character >= '0' && character <= '9') {
+ return character - '0';
+ } else if (character >= 'a' && character <= 'f') {
+ return character + (10 - 'a');
+ } else if (character >= 'A' && character <= 'F') {
+ return character + (10 - 'A');
}
+ return -1;
+}
- return ig;
+static int _parse_col8(const String &p_str, int p_ofs) {
+ return _parse_col4(p_str, p_ofs) * 16 + _parse_col4(p_str, p_ofs + 1);
}
Color Color::inverted() const {
@@ -302,49 +290,54 @@ Color Color::contrasted() const {
return c;
}
-Color Color::html(const String &p_color) {
- String color = p_color;
+Color Color::html(const String &p_rgba) {
+ String color = p_rgba;
if (color.length() == 0) {
return Color();
}
if (color[0] == '#') {
- color = color.substr(1, color.length() - 1);
- }
- if (color.length() == 3 || color.length() == 4) {
- String exp_color;
- for (int i = 0; i < color.length(); i++) {
- exp_color += color[i];
- exp_color += color[i];
- }
- color = exp_color;
+ color = color.substr(1);
}
+ // If enabled, use 1 hex digit per channel instead of 2.
+ // Other sizes aren't in the HTML/CSS spec but we could add them if desired.
+ bool is_shorthand = color.length() < 5;
bool alpha = false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
+ } else if (color.length() == 4) {
+ alpha = true;
+ } else if (color.length() == 3) {
+ alpha = false;
} else {
- ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + ".");
+ ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_rgba + ".");
}
- int a = 255;
- if (alpha) {
- a = _parse_col(color, 0);
- ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + ".");
+ float r, g, b, a = 1.0;
+ if (is_shorthand) {
+ r = _parse_col4(color, 0) / 15.0;
+ g = _parse_col4(color, 1) / 15.0;
+ b = _parse_col4(color, 2) / 15.0;
+ if (alpha) {
+ a = _parse_col4(color, 3) / 15.0;
+ }
+ } else {
+ r = _parse_col8(color, 0) / 255.0;
+ g = _parse_col8(color, 2) / 255.0;
+ b = _parse_col8(color, 4) / 255.0;
+ if (alpha) {
+ a = _parse_col8(color, 6) / 255.0;
+ }
}
+ ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_rgba + ".");
+ ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_rgba + ".");
- int from = alpha ? 2 : 0;
-
- int r = _parse_col(color, from + 0);
- ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + ".");
- int g = _parse_col(color, from + 2);
- ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + ".");
- int b = _parse_col(color, from + 4);
- 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);
+ return Color(r, g, b, a);
}
bool Color::html_is_valid(const String &p_color) {
@@ -354,41 +347,22 @@ bool Color::html_is_valid(const String &p_color) {
return false;
}
if (color[0] == '#') {
- color = color.substr(1, color.length() - 1);
+ color = color.substr(1);
}
- bool alpha = false;
-
- if (color.length() == 8) {
- alpha = true;
- } else if (color.length() == 6) {
- alpha = false;
- } else {
+ // Check if the amount of hex digits is valid.
+ int len = color.length();
+ if (!(len == 3 || len == 4 || len == 6 || len == 8)) {
return false;
}
- if (alpha) {
- int a = _parse_col(color, 0);
- if (a < 0) {
+ // Check if each hex digit is valid.
+ for (int i = 0; i < len; i++) {
+ if (_parse_col4(color, i) == -1) {
return false;
}
}
- int from = alpha ? 2 : 0;
-
- int r = _parse_col(color, from + 0);
- if (r < 0) {
- return false;
- }
- int g = _parse_col(color, from + 2);
- if (g < 0) {
- return false;
- }
- int b = _parse_col(color, from + 4);
- if (b < 0) {
- return false;
- }
-
return true;
}
@@ -416,7 +390,7 @@ String _to_hex(float p_val) {
String ret;
for (int i = 0; i < 2; i++) {
- CharType c[2] = { 0, 0 };
+ char32_t c[2] = { 0, 0 };
int lv = v & 0xF;
if (lv < 10) {
c[0] = '0' + lv;
@@ -425,7 +399,7 @@ String _to_hex(float p_val) {
}
v >>= 4;
- String cs = (const CharType *)c;
+ String cs = (const char32_t *)c;
ret = cs + ret;
}
@@ -438,7 +412,7 @@ String Color::to_html(bool p_alpha) const {
txt += _to_hex(g);
txt += _to_hex(b);
if (p_alpha) {
- txt = _to_hex(a) + txt;
+ txt += _to_hex(a);
}
return txt;
}
diff --git a/core/color.h b/core/color.h
index 258965fd16..096e97e9ae 100644
--- a/core/color.h
+++ b/core/color.h
@@ -185,7 +185,7 @@ struct Color {
static Color hex(uint32_t p_hex);
static Color hex64(uint64_t p_hex);
- static Color html(const String &p_color);
+ static Color html(const String &p_rgba);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
diff --git a/core/cowdata.h b/core/cowdata.h
index 82daefb5bd..79676e6d80 100644
--- a/core/cowdata.h
+++ b/core/cowdata.h
@@ -40,6 +40,7 @@
template <class T>
class Vector;
class String;
+class Char16String;
class CharString;
template <class T, class V>
class VMap;
@@ -49,6 +50,7 @@ class CowData {
template <class TV>
friend class Vector;
friend class String;
+ friend class Char16String;
friend class CharString;
template <class TV, class VV>
friend class VMap;
diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp
index b0dc47e655..117e47d538 100644
--- a/core/crypto/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -140,13 +140,19 @@ Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst
return ret ? FAILED : OK;
}
-Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
- int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
+Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
+ int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst);
return ret ? FAILED : OK;
}
-Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
- int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst);
+Error CryptoCore::AESContext::encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
+ size_t iv_off = 0; // Ignore and assume 16-byte alignment.
+ int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, &iv_off, p_iv, p_src, r_dst);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
+ int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
@@ -155,6 +161,12 @@ Error CryptoCore::AESContext::decrypt_cbc(size_t p_length, uint8_t r_iv[16], con
return ret ? FAILED : OK;
}
+Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
+ size_t iv_off = 0; // Ignore and assume 16-byte alignment.
+ int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_length, &iv_off, p_iv, p_src, r_dst);
+ return ret ? FAILED : OK;
+}
+
// CryptoCore
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
int b64len = p_src_len / 3 * 4 + 4 + 1;
diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h
index 82df9c23a8..9ab2871caa 100644
--- a/core/crypto/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -88,6 +88,8 @@ public:
Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
Error encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst);
Error decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst);
+ Error encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst);
+ Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst);
};
static String b64_encode_str(const uint8_t *p_src, int p_src_len);
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index 4427d94d2a..893f7f9103 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -64,6 +64,10 @@ void FuncRef::set_function(const StringName &p_func) {
function = p_func;
}
+StringName FuncRef::get_function() {
+ return function;
+}
+
bool FuncRef::is_valid() const {
if (id.is_null()) {
return false;
@@ -89,5 +93,6 @@ void FuncRef::_bind_methods() {
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("get_function"), &FuncRef::get_function);
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
}
diff --git a/core/func_ref.h b/core/func_ref.h
index 6b0b22bab5..75b84e705e 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -46,6 +46,7 @@ public:
Variant call_funcv(const Array &p_args);
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
+ StringName get_function();
bool is_valid() const;
FuncRef() {}
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index d984f6c524..f4048843fc 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -146,6 +146,8 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
+ static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return (uint32_t)p_uchar; }
+ static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return (uint32_t)p_uchar; }
static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
diff --git a/core/image.cpp b/core/image.cpp
index e2f353698f..b8a443eed2 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -363,6 +363,82 @@ void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int
r_size = ofs2 - ofs;
}
+Image::Image3DValidateError Image::validate_3d_image(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images) {
+ int w = p_width;
+ int h = p_height;
+ int d = p_depth;
+
+ int arr_ofs = 0;
+
+ while (true) {
+ for (int i = 0; i < d; i++) {
+ int idx = i + arr_ofs;
+ if (idx >= p_images.size()) {
+ return VALIDATE_3D_ERR_MISSING_IMAGES;
+ }
+ if (p_images[idx].is_null() || p_images[idx]->empty()) {
+ return VALIDATE_3D_ERR_IMAGE_EMPTY;
+ }
+ if (p_images[idx]->get_format() != p_format) {
+ return VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH;
+ }
+ if (p_images[idx]->get_width() != w || p_images[idx]->get_height() != h) {
+ return VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH;
+ }
+ if (p_images[idx]->has_mipmaps()) {
+ return VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS;
+ }
+ }
+
+ arr_ofs += d;
+
+ if (!p_mipmaps) {
+ break;
+ }
+
+ if (w == 1 && h == 1 && d == 1) {
+ break;
+ }
+
+ w = MAX(1, w >> 1);
+ h = MAX(1, h >> 1);
+ d = MAX(1, d >> 1);
+ }
+
+ if (arr_ofs != p_images.size()) {
+ return VALIDATE_3D_ERR_EXTRA_IMAGES;
+ }
+
+ return VALIDATE_3D_OK;
+}
+
+String Image::get_3d_image_validation_error_text(Image3DValidateError p_error) {
+ switch (p_error) {
+ case VALIDATE_3D_OK: {
+ return TTR("Ok");
+ } break;
+ case VALIDATE_3D_ERR_IMAGE_EMPTY: {
+ return TTR("Empty Image found");
+ } break;
+ case VALIDATE_3D_ERR_MISSING_IMAGES: {
+ return TTR("Missing Images");
+ } break;
+ case VALIDATE_3D_ERR_EXTRA_IMAGES: {
+ return TTR("Too many Images");
+ } break;
+ case VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH: {
+ return TTR("Image size mismatch");
+ } break;
+ case VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH: {
+ return TTR("Image format mismatch");
+ } break;
+ case VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS: {
+ return TTR("Image has included mipmaps");
+ } break;
+ }
+ return String();
+}
+
int Image::get_width() const {
return width;
}
diff --git a/core/image.h b/core/image.h
index d2572b072e..06794c7fed 100644
--- a/core/image.h
+++ b/core/image.h
@@ -230,6 +230,19 @@ public:
void get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const; //get where the mipmap begins in data
+ enum Image3DValidateError {
+ VALIDATE_3D_OK,
+ VALIDATE_3D_ERR_IMAGE_EMPTY,
+ VALIDATE_3D_ERR_MISSING_IMAGES,
+ VALIDATE_3D_ERR_EXTRA_IMAGES,
+ VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH,
+ VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH,
+ VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS,
+ };
+
+ static Image3DValidateError validate_3d_image(Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images);
+ static String get_3d_image_validation_error_text(Image3DValidateError p_error);
+
/**
* Resize the image, using the preferred interpolation method.
*/
diff --git a/core/input/SCsub b/core/input/SCsub
index f40978911b..740398b266 100644
--- a/core/input/SCsub
+++ b/core/input/SCsub
@@ -2,7 +2,6 @@
Import("env")
-from platform_methods import run_in_subprocess
import input_builders
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index 7b5abdd61b..2a3cb23202 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -8,6 +8,7 @@
03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000090000000000000,8BitDo FC30 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,
03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,
+03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
@@ -35,6 +36,7 @@
03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
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,
@@ -52,6 +54,7 @@
03000000d6200000e557000000000000,Batarang,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,
03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
030000006f0e00003201000000000000,Battlefield 4 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,
+03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
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,
@@ -83,6 +86,8 @@
03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,
+030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -98,8 +103,10 @@
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,
+03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
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,
030000009b2800003200000000000000,GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
+030000009b2800006000000000000000,GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,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,
@@ -157,6 +164,7 @@
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,lefttrigger:b6,righttrigger:b7,platform:Windows,
03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -183,8 +191,11 @@
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,
03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
+030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000001008000001e5000000000000,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:Windows,
03000000152000000182000000000000,NGDS,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:Windows,
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,
@@ -197,6 +208,7 @@
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
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,
+030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform: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,
@@ -232,8 +244,11 @@
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b13,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,
03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000000d0f00001100000000000000,REAL ARCADE PRO.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,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00006a00000000000000,Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00006b00000000000000,Real Arcade Pro.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:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -248,6 +263,7 @@
0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000006b140000020d000000000000,Revolution Pro Controller 2(1/2),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,
+030000006b140000130d000000000000,Revolution Pro Controller 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -275,16 +291,19 @@
03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
+03000000110100003114000000000000,SteelSeries Stratus Duo,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,
03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,
03000000790000001c18000000000000,STK-7024X,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,
03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,
03000000d620000011a7000000000000,Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+03000000457500002211000000000000,SZMY-POWER PC 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000007d0000000000000,T Mini Wireless,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,
030000004f0400000ab1000000000000,T.16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
03000000fa1900000706000000000000,Team 5,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,
03000000b50700001203000000000000,Techmobility X6-38V,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,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000004f0400000ed0000000000000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
@@ -306,6 +325,7 @@
03000000790000001a18000000000000,Venom,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,
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,
030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:+a3,righty:+a4,start:b4,x:b2,y:b3,platform:Windows,
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
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,
@@ -315,28 +335,39 @@
03000000786901006e70000000000000,XInput 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,
xinput,XInput 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,
03000000790000004f18000000000000,ZD-T Android,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,
-030000009b2800006000000000000000,GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
+03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
# Mac OS X
030000008f0e00000300000009010000,2In1 USB Joystick,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
+03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
+03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00001590000001000000,8BitDo N30 Pro 2,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:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00006528000000010000,8BitDo N30 Pro 2,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:Mac OS X,
+030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000022000000090000001000000,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:Mac OS X,
03000000203800000900000000010000,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:Mac OS X,
03000000c82d00000190000001000000,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:Mac OS X,
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,
+03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
+03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
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,
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,
+03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
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,
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -378,11 +409,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,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,
+03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
+03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,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,
03000000d620000011a7000000020000,Nintendo Switch Core (Plus) Wired 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: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,
+03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,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:Mac OS X,
+030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform: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,
030000004c050000da0c000000010000,Playstation Classic 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: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,
@@ -397,12 +432,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
+03000000321500000011000000010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform: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,
030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000006b140000130d000000010000,Revolution Pro Controller 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: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,
03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,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,
03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,
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,
@@ -418,18 +455,22 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
+03000000457500002211000000010000,SZMY-POWER PC 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: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,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
+030000004f0400000ed0000000020000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000006f0e00000702000003060000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
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,
+030000005e040000050b000003090000,Xbox Elite Wireless Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,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,
@@ -439,8 +480,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
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,
+03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
# Linux
+03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform: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,
05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00001590000011010000,8BitDo N30 Pro 2,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,
@@ -465,8 +508,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
@@ -475,10 +520,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
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,
+03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -513,22 +560,27 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.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:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000000d0f00008500000010010000,HORI Fighting Commander,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,
+030000000d0f00008600000002010000,Hori Fighting Commander,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,
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,
+030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
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,
030000000d0f00006700000001010000,HORIPAD 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,
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
+03000000242e00008816000001010000,Hyperkin X91,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,
03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
050000006964726f69643a636f6e0000,idroid:con,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,
03000000b50700001503000010010000,impact,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,
03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
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,
+03000000632500007505000011010000,Ipega PG-9099 - Bluetooth 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,
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,
@@ -567,7 +619,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,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,
+03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,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:b0,y:b3,platform:Linux,
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
0300000079000000d218000011010000,Mayflash 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,
03000000d620000010a7000011010000,Mayflash Magic NS,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,
@@ -588,14 +640,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
+03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
+030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,
060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
-050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,x:b3,y:b2,back:b9,guide:b11,start:b10,leftstick:b12,rightstick:b13,leftshoulder:b5,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b7,righttrigger:b8,platform:Linux,
-030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,x:b3,y:b2,back:b9,guide:b11,start:b10,leftstick:b12,rightstick:b13,leftshoulder:b5,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b7,righttrigger:b8,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
+050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
+030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,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:b3,y:b2,platform:Linux,
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,
@@ -603,19 +658,29 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
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,
+19000000010000000100000001010000,odroidgo2_joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
+19000000010000000200000011000000,odroidgo2_joypad_v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,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,
03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,
+03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
+030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -640,18 +705,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
+050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
+030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
-030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
+030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000008916000000fe000024010000,Razer Sabertooth,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,
03000000c6240000045d000024010000,Razer Sabertooth,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,
03000000c6240000045d000025010000,Razer Sabertooth,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,
@@ -662,11 +730,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,
0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+030000006b140000130d000011010000,Revolution Pro Controller 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:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00001f01000000010000,Rock Candy,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,
030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30600001005000000010000,Saitek Saitek P150,platform:Linux,a:b0,b:b1,y:b4,x:b3,leftshoulder:b7,rightshoulder:b2,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,lefttrigger:b6,righttrigger:b5,
03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
@@ -674,6 +742,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
+03000000a30600001005000000010000,Saitek Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -687,7 +756,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
@@ -695,9 +766,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,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,
05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,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,
03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,x:b1,y:b3,back:b7,start:b8,leftshoulder:b6,rightshoulder:b9,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b5,platform:Linux,
+030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -705,7 +777,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,x:b3,y:b5,back:b11,start:b1,leftstick:b10,rightstick:b0,leftshoulder:b6,rightshoulder:b8,leftx:a0,lefty:a1,lefttrigger:b7,righttrigger:b9,platform:Linux,
+030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -722,8 +795,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000790000000600000007010000,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:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
+030000006f0e00000702000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
05000000ac0500003232000001000000,VR-BOX,a:b0,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:b2,y:b3,platform:Linux,
03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+050000000d0f0000f600000001000000,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000005e0400008e02000010010000,X360 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,
030000005e0400008e02000014010000,X360 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,
030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,
@@ -735,44 +810,70 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000ea02000000000000,Xbox One Wireless 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,
050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
05000000172700004431000029010000,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:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000005e0400008e02000000010000,xbox360 Wireless EasySMX,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,
-030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
+03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
# Android
+05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
+050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,platform:Android,
+05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
+0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b1,b:b0,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b3,y:b2,platform:Android,
64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
+7573622067616d657061642020202020,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:Android,
050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,platform:Android,
37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
+050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
+62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
+050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
+30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android,
050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,
-7573622067616d657061642020202020,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:Android,
+050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
# iOS
05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index ac032b7d10..2bf8792421 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -95,6 +95,8 @@ List<StringName> InputMap::get_actions() const {
}
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const {
+ ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
+
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
const Ref<InputEvent> e = E->get();
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index 99ca8107e4..7480262835 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -180,8 +180,95 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
ERR_FAIL_V(-1);
}
+/**
+ This will handle both Gzip and Deflat streams. It will automatically allocate the output buffer into the provided p_dst_vect Vector.
+ This is required for compressed data who's final uncompressed size is unknown, as is the case for HTTP response bodies.
+ This is much slower however than using Compression::decompress because it may result in multiple full copies of the output buffer.
+*/
+int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode) {
+ int ret;
+ uint8_t *dst = nullptr;
+ int out_mark = 0;
+ z_stream strm;
+
+ ERR_FAIL_COND_V(p_src_size <= 0, Z_DATA_ERROR);
+
+ // This function only supports GZip and Deflate
+ int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
+ ERR_FAIL_COND_V(p_mode != MODE_DEFLATE && p_mode != MODE_GZIP, Z_ERRNO);
+
+ // Initialize the stream
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = 0;
+ strm.next_in = Z_NULL;
+
+ int err = inflateInit2(&strm, window_bits);
+ ERR_FAIL_COND_V(err != Z_OK, -1);
+
+ // Setup the stream inputs
+ strm.next_in = (Bytef *)p_src;
+ strm.avail_in = p_src_size;
+
+ // Ensure the destination buffer is empty
+ p_dst_vect->resize(0);
+
+ // decompress until deflate stream ends or end of file
+ do {
+ // Add another chunk size to the output buffer
+ // This forces a copy of the whole buffer
+ p_dst_vect->resize(p_dst_vect->size() + gzip_chunk);
+ // Get pointer to the actual output buffer
+ dst = p_dst_vect->ptrw();
+
+ // Set the stream to the new output stream
+ // Since it was copied, we need to reset the stream to the new buffer
+ strm.next_out = &(dst[out_mark]);
+ strm.avail_out = gzip_chunk;
+
+ // run inflate() on input until output buffer is full and needs to be resized
+ // or input runs out
+ do {
+ ret = inflate(&strm, Z_SYNC_FLUSH);
+
+ switch (ret) {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ [[fallthrough]];
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR:
+ WARN_PRINT(strm.msg);
+ (void)inflateEnd(&strm);
+ p_dst_vect->resize(0);
+ return ret;
+ }
+ } while (strm.avail_out > 0 && strm.avail_in > 0);
+
+ out_mark += gzip_chunk;
+
+ // Encorce max output size
+ if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) {
+ (void)inflateEnd(&strm);
+ p_dst_vect->resize(0);
+ return Z_BUF_ERROR;
+ }
+ } while (ret != Z_STREAM_END);
+
+ // If all done successfully, resize the output if it's larger than the actual output
+ if (ret == Z_STREAM_END && (unsigned long)p_dst_vect->size() > strm.total_out) {
+ p_dst_vect->resize(strm.total_out);
+ }
+
+ // clean up and return
+ (void)inflateEnd(&strm);
+ return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
int Compression::zlib_level = Z_DEFAULT_COMPRESSION;
int Compression::gzip_level = Z_DEFAULT_COMPRESSION;
int Compression::zstd_level = 3;
bool Compression::zstd_long_distance_matching = false;
int Compression::zstd_window_log_size = 27; // ZSTD_WINDOWLOG_LIMIT_DEFAULT
+int Compression::gzip_chunk = 16384;
diff --git a/core/io/compression.h b/core/io/compression.h
index f195f96ba5..c103fa8eae 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -32,6 +32,7 @@
#define COMPRESSION_H
#include "core/typedefs.h"
+#include "core/vector.h"
class Compression {
public:
@@ -40,6 +41,7 @@ public:
static int zstd_level;
static bool zstd_long_distance_matching;
static int zstd_window_log_size;
+ static int gzip_chunk;
enum Mode {
MODE_FASTLZ,
@@ -51,6 +53,7 @@ public:
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD);
static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
+ static int decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_size, const uint8_t *p_src, int p_src_size, Mode p_mode);
Compression() {}
};
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 5938914cb0..eb684f457e 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -37,52 +37,54 @@
#include <stdio.h>
-#define COMP_MAGIC 0x43454447
-
-Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
+Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) {
ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
pos = 0;
eofed = false;
+ use_magic = p_with_magic;
if (p_mode == MODE_WRITE_AES256) {
data.clear();
writing = true;
file = p_base;
- mode = p_mode;
key = p_key;
} else if (p_mode == MODE_READ) {
writing = false;
key = p_key;
- uint32_t magic = p_base->get_32();
- ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED);
- mode = Mode(p_base->get_32());
- ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT);
- ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT);
+ if (use_magic) {
+ uint32_t magic = p_base->get_32();
+ ERR_FAIL_COND_V(magic != ENCRYPTED_HEADER_MAGIC, ERR_FILE_UNRECOGNIZED);
+ }
unsigned char md5d[16];
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
+
+ unsigned char iv[16];
+ for (int i = 0; i < 16; i++) {
+ iv[i] = p_base->get_8();
+ }
+
base = p_base->get_position();
ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT);
uint32_t ds = length;
if (ds % 16) {
ds += 16 - (ds % 16);
}
-
data.resize(ds);
uint32_t blen = p_base->get_buffer(data.ptrw(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
- CryptoCore::AESContext ctx;
- ctx.set_decode_key(key.ptrw(), 256);
+ {
+ CryptoCore::AESContext ctx;
- for (size_t i = 0; i < ds; i += 16) {
- ctx.decrypt_ecb(&data.write[i], &data.write[i]);
+ ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!
+ ctx.decrypt_cfb(ds, iv, data.ptrw(), data.ptrw());
}
data.resize(length);
@@ -119,6 +121,25 @@ void FileAccessEncrypted::close() {
return;
}
+ _release();
+
+ file->close();
+ memdelete(file);
+
+ file = nullptr;
+}
+
+void FileAccessEncrypted::release() {
+ if (!file) {
+ return;
+ }
+
+ _release();
+
+ file = nullptr;
+}
+
+void FileAccessEncrypted::_release() {
if (writing) {
Vector<uint8_t> compressed;
size_t len = data.size();
@@ -138,27 +159,23 @@ void FileAccessEncrypted::close() {
CryptoCore::AESContext ctx;
ctx.set_encode_key(key.ptrw(), 256);
- for (size_t i = 0; i < len; i += 16) {
- ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
+ if (use_magic) {
+ file->store_32(ENCRYPTED_HEADER_MAGIC);
}
- file->store_32(COMP_MAGIC);
- file->store_32(mode);
-
file->store_buffer(hash, 16);
file->store_64(data.size());
- file->store_buffer(compressed.ptr(), compressed.size());
- file->close();
- memdelete(file);
- file = nullptr;
- data.clear();
+ unsigned char iv[16];
+ for (int i = 0; i < 16; i++) {
+ iv[i] = Math::rand() % 256;
+ file->store_8(iv[i]);
+ }
- } else {
- file->close();
- memdelete(file);
+ ctx.encrypt_cfb(len, iv, compressed.ptrw(), compressed.ptrw());
+
+ file->store_buffer(compressed.ptr(), compressed.size());
data.clear();
- file = nullptr;
}
}
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index e269c1e30c..fddc6842f3 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -33,6 +33,8 @@
#include "core/os/file_access.h"
+#define ENCRYPTED_HEADER_MAGIC 0x43454447
+
class FileAccessEncrypted : public FileAccess {
public:
enum Mode {
@@ -42,7 +44,6 @@ public:
};
private:
- Mode mode = MODE_MAX;
Vector<uint8_t> key;
bool writing = false;
FileAccess *file = nullptr;
@@ -51,13 +52,17 @@ private:
Vector<uint8_t> data;
mutable int pos = 0;
mutable bool eofed = false;
+ bool use_magic = true;
+
+ void _release();
public:
- Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode);
+ Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true);
Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode);
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
+ virtual void release(); ///< finish and keep base file open
virtual bool is_open() const; ///< true when file is open
virtual String get_path() const; /// returns the path for the current open file
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 37240f234a..8fdbb650d4 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -30,13 +30,15 @@
#include "file_access_pack.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/script_language.h"
#include "core/version.h"
#include <stdio.h>
-Error PackedData::add_pack(const String &p_path, bool p_replace_files) {
+Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_offset) {
for (int i = 0; i < sources.size(); i++) {
- if (sources[i]->try_open_pack(p_path, p_replace_files)) {
+ if (sources[i]->try_open_pack(p_path, p_replace_files, p_offset)) {
return OK;
}
}
@@ -44,13 +46,14 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files) {
return ERR_FILE_UNRECOGNIZED;
}
-void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) {
+void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) {
PathMD5 pmd5(path.md5_buffer());
- //printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
+ //printf("adding path %s, %lli, %lli\n", path.utf8().get_data(), pmd5.a, pmd5.b);
bool exists = files.has(pmd5);
PackedFile pf;
+ pf.encrypted = p_encrypted;
pf.pack = pkg_path;
pf.offset = ofs;
pf.size = size;
@@ -123,15 +126,24 @@ PackedData::~PackedData() {
//////////////////////////////////////////////////////////////////
-bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) {
+bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
return false;
}
+ f->seek(p_offset);
+
uint32_t magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
+ // loading with offset feature not supported for self contained exe files
+ if (p_offset != 0) {
+ f->close();
+ memdelete(f);
+ ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported.");
+ }
+
//maybe at the end.... self contained exe
f->seek_end();
f->seek(f->get_position() - 4);
@@ -170,6 +182,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
}
+ uint32_t pack_flags = f->get_32();
+ uint64_t file_base = f->get_64();
+
+ bool enc_directory = (pack_flags & PACK_DIR_ENCRYPTED);
+
for (int i = 0; i < 16; i++) {
//reserved
f->get_32();
@@ -177,6 +194,30 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
int file_count = f->get_32();
+ if (enc_directory) {
+ FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ if (!fae) {
+ f->close();
+ memdelete(f);
+ ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
+ }
+
+ Vector<uint8_t> key;
+ key.resize(32);
+ for (int i = 0; i < key.size(); i++) {
+ key.write[i] = script_encryption_key[i];
+ }
+
+ Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
+ if (err) {
+ f->close();
+ memdelete(f);
+ memdelete(fae);
+ ERR_FAIL_V_MSG(false, "Can't open encrypted pack directory.");
+ }
+ f = fae;
+ }
+
for (int i = 0; i < file_count; i++) {
uint32_t sl = f->get_32();
CharString cs;
@@ -187,11 +228,13 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
String path;
path.parse_utf8(cs.ptr());
- uint64_t ofs = f->get_64();
+ uint64_t ofs = file_base + f->get_64();
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5, 16);
- PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this, p_replace_files);
+ uint32_t flags = f->get_32();
+
+ PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED));
}
f->close();
@@ -225,7 +268,7 @@ void FileAccessPack::seek(size_t p_position) {
eof = false;
}
- f->seek(pf.offset + p_position);
+ f->seek(off + p_position);
pos = p_position;
}
@@ -310,12 +353,35 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
f->seek(pf.offset);
+ off = pf.offset;
+
+ if (pf.encrypted) {
+ FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ if (!fae) {
+ ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
+ }
+
+ Vector<uint8_t> key;
+ key.resize(32);
+ for (int i = 0; i < key.size(); i++) {
+ key.write[i] = script_encryption_key[i];
+ }
+
+ Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false);
+ if (err) {
+ memdelete(fae);
+ ERR_FAIL_MSG("Can't open encrypted pack-referenced file '" + String(pf.pack) + "'.");
+ }
+ f = fae;
+ off = 0;
+ }
pos = 0;
eof = false;
}
FileAccessPack::~FileAccessPack() {
if (f) {
+ f->close();
memdelete(f);
}
}
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 348bc0c450..d934b0deb5 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -40,7 +40,15 @@
// Godot's packed file magic header ("GDPC" in ASCII).
#define PACK_HEADER_MAGIC 0x43504447
// The current packed file format version number.
-#define PACK_FORMAT_VERSION 1
+#define PACK_FORMAT_VERSION 2
+
+enum PackFlags {
+ PACK_DIR_ENCRYPTED = 1 << 0
+};
+
+enum PackFileFlags {
+ PACK_FILE_ENCRYPTED = 1 << 0
+};
class PackSource;
@@ -56,6 +64,7 @@ public:
uint64_t size;
uint8_t md5[16];
PackSource *src;
+ bool encrypted;
};
private:
@@ -102,13 +111,13 @@ private:
public:
void add_pack_source(PackSource *p_source);
- void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files); // for PackSource
+ void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; }
- Error add_pack(const String &p_path, bool p_replace_files);
+ Error add_pack(const String &p_path, bool p_replace_files, size_t p_offset);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
@@ -119,14 +128,14 @@ public:
class PackSource {
public:
- virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0;
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
public:
- virtual bool try_open_pack(const String &p_path, bool p_replace_files);
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
@@ -135,6 +144,7 @@ class FileAccessPack : public FileAccess {
mutable size_t pos;
mutable bool eof;
+ uint64_t off;
FileAccess *f;
virtual Error _open(const String &p_path, int p_mode_flags);
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index c3a62706c7..ce402fe8ed 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -147,8 +147,11 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
return pkg;
}
-bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
- //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
+bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset = 0) {
+ //printf("opening zip pack %s, %i, %i\n", p_name.utf8().get_data(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
+ // load with offset feature only supported for PCK files
+ ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives.");
+
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) {
return false;
}
@@ -197,8 +200,8 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
files[fname] = f;
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this, p_replace_files);
- //printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str());
+ PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this, p_replace_files, false);
+ //printf("packed data add path %s, %s\n", p_name.utf8().get_data(), fname.utf8().get_data());
if ((i + 1) < gi.number_entry) {
unzGoToNextFile(zfile);
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index 776e830f36..c251b3c424 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef MINIZIP_ENABLED
-
#ifndef FILE_ACCESS_ZIP_H
#define FILE_ACCESS_ZIP_H
+#ifdef MINIZIP_ENABLED
+
#include "core/io/file_access_pack.h"
#include "core/map.h"
@@ -69,7 +69,7 @@ public:
bool file_exists(String p_name) const;
- virtual bool try_open_pack(const String &p_path, bool p_replace_files);
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset);
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive *get_singleton();
@@ -79,7 +79,7 @@ public:
};
class FileAccessZip : public FileAccess {
- unzFile zfile;
+ unzFile zfile = nullptr;
unz_file_info64 file_info;
mutable bool at_eof;
@@ -113,6 +113,6 @@ public:
~FileAccessZip();
};
-#endif // FILE_ACCESS_ZIP_H
-
#endif // MINIZIP_ENABLED
+
+#endif // FILE_ACCESS_ZIP_H
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index c7a0ae5605..d0fb63b958 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -71,7 +71,7 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
}
int n = 0;
- CharType c = p_string[i];
+ char32_t c = p_string[i];
if (c >= '0' && c <= '9') {
n = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -101,7 +101,7 @@ void IP_Address::_parse_ipv6(const String &p_string) {
int parts_idx = 0;
for (int i = 0; i < p_string.length(); i++) {
- CharType c = p_string[i];
+ char32_t c = p_string[i];
if (c == ':') {
if (i == 0) {
continue; // next must be a ":"
diff --git a/core/io/json.cpp b/core/io/json.cpp
index 8bdd6385cb..1b89d966fd 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -125,7 +125,7 @@ String JSON::print(const Variant &p_var, const String &p_indent, bool p_sort_key
return _print_var(p_var, p_indent, 0, p_sort_keys);
}
-Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
+Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
while (p_len > 0) {
switch (p_str[index]) {
case '\n': {
@@ -180,12 +180,12 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
} else if (p_str[index] == '\\') {
//escaped characters...
index++;
- CharType next = p_str[index];
+ char32_t next = p_str[index];
if (next == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -206,7 +206,7 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
- CharType c = p_str[index + j + 1];
+ char32_t c = p_str[index + j + 1];
if (c == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
@@ -215,7 +215,7 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
r_err_str = "Malformed hex constant in string";
return ERR_PARSE_ERROR;
}
- CharType v;
+ char32_t v;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -264,7 +264,7 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
if (p_str[index] == '-' || (p_str[index] >= '0' && p_str[index] <= '9')) {
//a number
- const CharType *rptr;
+ const char32_t *rptr;
double number = String::to_float(&p_str[index], &rptr);
index += (rptr - &p_str[index]);
r_token.type = TK_NUMBER;
@@ -293,7 +293,7 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
return ERR_PARSE_ERROR;
}
-Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
+Error JSON::_parse_value(Variant &value, Token &token, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str) {
if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d;
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
@@ -337,7 +337,7 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in
}
}
-Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
+Error JSON::_parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str) {
Token token;
bool need_comma = false;
@@ -375,7 +375,7 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
return ERR_PARSE_ERROR;
}
-Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
+Error JSON::_parse_object(Dictionary &object, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str) {
bool at_key = true;
String key;
Token token;
@@ -439,7 +439,7 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
}
Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) {
- const CharType *str = p_json.ptr();
+ const char32_t *str = p_json.ptr();
int idx = 0;
int len = p_json.length();
Token token;
diff --git a/core/io/json.h b/core/io/json.h
index 4fc5630a93..9122228163 100644
--- a/core/io/json.h
+++ b/core/io/json.h
@@ -65,10 +65,10 @@ class JSON {
static String _print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys);
- static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
- static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
- static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
- static Error _parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
+ static Error _get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
+ static Error _parse_value(Variant &value, Token &token, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str);
+ static Error _parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str);
+ static Error _parse_object(Dictionary &object, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str);
public:
static String print(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true);
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 374b2a5e07..5480d3c535 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -30,36 +30,58 @@
#include "pck_packer.h"
+#include "core/crypto/crypto_core.h"
+#include "core/io/file_access_encrypted.h"
#include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION
#include "core/os/file_access.h"
#include "core/version.h"
-static uint64_t _align(uint64_t p_n, int p_alignment) {
- if (p_alignment == 0) {
- return p_n;
+static int _get_pad(int p_alignment, int p_n) {
+ int rest = p_n % p_alignment;
+ int pad = 0;
+ if (rest > 0) {
+ pad = p_alignment - rest;
}
- uint64_t rest = p_n % p_alignment;
- if (rest == 0) {
- return p_n;
- } else {
- return p_n + (p_alignment - rest);
- }
-}
-
-static void _pad(FileAccess *p_file, int p_bytes) {
- for (int i = 0; i < p_bytes; i++) {
- p_file->store_8(0);
- }
+ return pad;
}
void PCKPacker::_bind_methods() {
- ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path"), &PCKPacker::add_file);
+ ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(0), DEFVAL(String()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false));
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
}
-Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
+Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) {
+ ERR_FAIL_COND_V_MSG((p_key.empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
+
+ String _key = p_key.to_lower();
+ key.resize(32);
+ for (int i = 0; i < 32; i++) {
+ int v = 0;
+ if (i * 2 < _key.length()) {
+ char32_t ct = _key[i * 2];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct << 4;
+ }
+
+ if (i * 2 + 1 < _key.length()) {
+ char32_t ct = _key[i * 2 + 1];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct;
+ }
+ key.write[i] = v;
+ }
+ enc_dir = p_encrypt_directory;
+
if (file != nullptr) {
memdelete(file);
}
@@ -76,16 +98,19 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file->store_32(VERSION_MINOR);
file->store_32(VERSION_PATCH);
- for (int i = 0; i < 16; i++) {
- file->store_32(0); // reserved
+ uint32_t pack_flags = 0;
+ if (enc_dir) {
+ pack_flags |= PACK_DIR_ENCRYPTED;
}
+ file->store_32(pack_flags); // flags
files.clear();
+ ofs = 0;
return OK;
}
-Error PCKPacker::add_file(const String &p_file, const String &p_src) {
+Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encrypt) {
FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
if (!f) {
return ERR_FILE_CANT_OPEN;
@@ -94,8 +119,32 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) {
File pf;
pf.path = p_file;
pf.src_path = p_src;
+ pf.ofs = ofs;
pf.size = f->get_len();
- pf.offset_offset = 0;
+
+ Vector<uint8_t> data = FileAccess::get_file_as_array(p_src);
+ {
+ unsigned char hash[16];
+ CryptoCore::md5(data.ptr(), data.size(), hash);
+ pf.md5.resize(16);
+ for (int i = 0; i < 16; i++) {
+ pf.md5.write[i] = hash[i];
+ }
+ }
+ pf.encrypted = p_encrypt;
+
+ uint64_t _size = pf.size;
+ if (p_encrypt) { // Add encryption overhead.
+ if (_size % 16) { // Pad to encryption block size.
+ _size += 16 - (_size % 16);
+ }
+ _size += 16; // hash
+ _size += 8; // data size
+ _size += 16; // iv
+ }
+
+ int pad = _get_pad(alignment, ofs + _size);
+ ofs = ofs + _size + pad;
files.push_back(pf);
@@ -108,27 +157,64 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) {
Error PCKPacker::flush(bool p_verbose) {
ERR_FAIL_COND_V_MSG(!file, ERR_INVALID_PARAMETER, "File must be opened before use.");
- // write the index
+ int64_t file_base_ofs = file->get_position();
+ file->store_64(0); // files base
+ for (int i = 0; i < 16; i++) {
+ file->store_32(0); // reserved
+ }
+
+ // write the index
file->store_32(files.size());
+ FileAccessEncrypted *fae = nullptr;
+ FileAccess *fhead = file;
+
+ if (enc_dir) {
+ fae = memnew(FileAccessEncrypted);
+ ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE);
+
+ Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
+
+ fhead = fae;
+ }
+
for (int i = 0; i < files.size(); i++) {
- file->store_pascal_string(files[i].path);
- files.write[i].offset_offset = file->get_position();
- file->store_64(0); // offset
- file->store_64(files[i].size); // size
-
- // # empty md5
- file->store_32(0);
- file->store_32(0);
- file->store_32(0);
- file->store_32(0);
+ int string_len = files[i].path.utf8().length();
+ int pad = _get_pad(4, string_len);
+
+ fhead->store_32(string_len + pad);
+ fhead->store_buffer((const uint8_t *)files[i].path.utf8().get_data(), string_len);
+ for (int j = 0; j < pad; j++) {
+ fhead->store_8(0);
+ }
+
+ fhead->store_64(files[i].ofs);
+ fhead->store_64(files[i].size); // pay attention here, this is where file is
+ fhead->store_buffer(files[i].md5.ptr(), 16); //also save md5 for file
+
+ uint32_t flags = 0;
+ if (files[i].encrypted) {
+ flags |= PACK_FILE_ENCRYPTED;
+ }
+ fhead->store_32(flags);
+ }
+
+ if (fae) {
+ fae->release();
+ memdelete(fae);
}
- uint64_t ofs = file->get_position();
- ofs = _align(ofs, alignment);
+ int header_padding = _get_pad(alignment, file->get_position());
+ for (int i = 0; i < header_padding; i++) {
+ file->store_8(Math::rand() % 256);
+ }
- _pad(file, ofs - file->get_position());
+ int64_t file_base = file->get_position();
+ file->seek(file_base_ofs);
+ file->store_64(file_base); // update files base
+ file->seek(file_base);
const uint32_t buf_max = 65536;
uint8_t *buf = memnew_arr(uint8_t, buf_max);
@@ -137,26 +223,41 @@ Error PCKPacker::flush(bool p_verbose) {
for (int i = 0; i < files.size(); i++) {
FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
uint64_t to_write = files[i].size;
+
+ fae = nullptr;
+ FileAccess *ftmp = file;
+ if (files[i].encrypted) {
+ fae = memnew(FileAccessEncrypted);
+ ERR_FAIL_COND_V(!fae, ERR_CANT_CREATE);
+
+ Error err = fae->open_and_parse(file, key, FileAccessEncrypted::MODE_WRITE_AES256, false);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
+ ftmp = fae;
+ }
+
while (to_write > 0) {
int read = src->get_buffer(buf, MIN(to_write, buf_max));
- file->store_buffer(buf, read);
+ ftmp->store_buffer(buf, read);
to_write -= read;
}
- uint64_t pos = file->get_position();
- file->seek(files[i].offset_offset); // go back to store the file's offset
- file->store_64(ofs);
- file->seek(pos);
+ if (fae) {
+ fae->release();
+ memdelete(fae);
+ }
- ofs = _align(ofs + files[i].size, alignment);
- _pad(file, ofs - pos);
+ int pad = _get_pad(alignment, file->get_position());
+ for (int j = 0; j < pad; j++) {
+ file->store_8(Math::rand() % 256);
+ }
src->close();
memdelete(src);
count += 1;
- if (p_verbose && files.size() > 0) {
+ const int file_num = files.size();
+ if (p_verbose && (file_num > 0)) {
if (count % 100 == 0) {
- printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
+ printf("%i/%i (%.2f)\r", count, file_num, float(count) / file_num * 100);
fflush(stdout);
}
}
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 2929967a68..a6054dff2c 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -40,20 +40,26 @@ class PCKPacker : public Reference {
FileAccess *file = nullptr;
int alignment;
+ uint64_t ofs = 0;
+
+ Vector<uint8_t> key;
+ bool enc_dir = false;
static void _bind_methods();
struct File {
String path;
String src_path;
- int size;
- uint64_t offset_offset;
+ uint64_t ofs;
+ uint64_t size;
+ bool encrypted;
+ Vector<uint8_t> md5;
};
Vector<File> files;
public:
- Error pck_start(const String &p_file, int p_alignment = 0);
- Error add_file(const String &p_file, const String &p_src);
+ Error pck_start(const String &p_file, int p_alignment = 0, const String &p_key = String(), bool p_encrypt_directory = false);
+ Error add_file(const String &p_file, const String &p_src, bool p_encrypt = false);
Error flush(bool p_verbose = false);
PCKPacker() {}
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 534f3e44de..b5c598e860 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -195,7 +195,8 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
return res;
}
- ERR_FAIL_COND_V_MSG(found, RES(), "Failed loading resource: " + p_path + ".");
+ ERR_FAIL_COND_V_MSG(found, RES(),
+ vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path));
#ifdef TOOLS_ENABLED
FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES);
@@ -999,6 +1000,9 @@ void ResourceLoader::load_translation_remaps() {
void ResourceLoader::clear_translation_remaps() {
translation_remaps.clear();
+ while (remapped_list.first() != nullptr) {
+ remapped_list.remove(remapped_list.first());
+ }
}
void ResourceLoader::load_path_remaps() {
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index b11267b60f..fc75ac7d1e 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -36,7 +36,7 @@
VARIANT_ENUM_CAST(XMLParser::NodeType);
-static bool _equalsn(const CharType *str1, const CharType *str2, int len) {
+static bool _equalsn(const char32_t *str1, const char32_t *str2, int len) {
int i;
for (i = 0; i < len && str1[i] && str2[i]; ++i) {
if (str1[i] != str2[i]) {
@@ -64,7 +64,7 @@ String XMLParser::_replace_special_characters(const String &origstr) {
int specialChar = -1;
for (int i = 0; i < (int)special_characters.size(); ++i) {
- const CharType *p = &origstr[pos] + 1;
+ const char32_t *p = &origstr[pos] + 1;
if (_equalsn(&special_characters[i][1], p, special_characters[i].length() - 1)) {
specialChar = i;
diff --git a/core/list.h b/core/list.h
index f850db5241..1cef3c484d 100644
--- a/core/list.h
+++ b/core/list.h
@@ -395,28 +395,38 @@ public:
ERR_FAIL_COND(p_A->data != _data);
ERR_FAIL_COND(p_B->data != _data);
+ if (p_A == p_B) {
+ return;
+ }
Element *A_prev = p_A->prev_ptr;
Element *A_next = p_A->next_ptr;
+ Element *B_prev = p_B->prev_ptr;
+ Element *B_next = p_B->next_ptr;
- p_A->next_ptr = p_B->next_ptr;
- p_A->prev_ptr = p_B->prev_ptr;
-
- p_B->next_ptr = A_next;
- p_B->prev_ptr = A_prev;
-
- if (p_A->prev_ptr) {
- p_A->prev_ptr->next_ptr = p_A;
+ if (A_prev) {
+ A_prev->next_ptr = p_B;
+ } else {
+ _data->first = p_B;
}
- if (p_A->next_ptr) {
- p_A->next_ptr->prev_ptr = p_A;
+ if (B_prev) {
+ B_prev->next_ptr = p_A;
+ } else {
+ _data->first = p_A;
}
-
- if (p_B->prev_ptr) {
- p_B->prev_ptr->next_ptr = p_B;
+ if (A_next) {
+ A_next->prev_ptr = p_B;
+ } else {
+ _data->last = p_B;
}
- if (p_B->next_ptr) {
- p_B->next_ptr->prev_ptr = p_B;
+ if (B_next) {
+ B_next->prev_ptr = p_A;
+ } else {
+ _data->last = p_A;
}
+ p_A->prev_ptr = A_next == p_B ? p_B : B_prev;
+ p_A->next_ptr = B_next == p_A ? p_B : B_next;
+ p_B->prev_ptr = B_next == p_A ? p_A : A_prev;
+ p_B->next_ptr = A_next == p_B ? p_A : A_next;
}
/**
* copy the list
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 91f533eafb..43d4a63cd3 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -121,7 +121,7 @@ struct AudioFrame {
r = p_frame.r;
}
- _ALWAYS_INLINE_ AudioFrame operator=(const AudioFrame &p_frame) {
+ _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) {
l = p_frame.l;
r = p_frame.r;
return *this;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index dd38e25bb1..a712ae7e3e 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -113,19 +113,22 @@ bool Basis::is_rotation() const {
return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal();
}
+#ifdef MATH_CHECKS
+// This method is only used once, in diagonalize. If it's desired elsewhere, feel free to remove the #ifdef.
bool Basis::is_symmetric() const {
- if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[0][1], elements[1][0])) {
return false;
}
- if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[0][2], elements[2][0])) {
return false;
}
- if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) {
+ if (!Math::is_equal_approx(elements[1][2], elements[2][1])) {
return false;
}
return true;
}
+#endif
Basis Basis::diagonalize() {
//NOTE: only implemented for symmetric matrices
@@ -737,18 +740,6 @@ bool Basis::is_equal_approx(const Basis &p_basis) const {
return elements[0].is_equal_approx(p_basis.elements[0]) && elements[1].is_equal_approx(p_basis.elements[1]) && elements[2].is_equal_approx(p_basis.elements[2]);
}
-bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) {
- return false;
- }
- }
- }
-
- return true;
-}
-
bool Basis::operator==(const Basis &p_matrix) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
diff --git a/core/math/basis.h b/core/math/basis.h
index 985fb0e44f..2584f1ff48 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -36,7 +36,11 @@
class Basis {
public:
- Vector3 elements[3];
+ Vector3 elements[3] = {
+ Vector3(1, 0, 0),
+ Vector3(0, 1, 0),
+ Vector3(0, 0, 1)
+ };
_FORCE_INLINE_ const Vector3 &operator[](int axis) const {
return elements[axis];
@@ -142,9 +146,6 @@ public:
}
bool is_equal_approx(const Basis &p_basis) const;
- // TODO: Break compatibility in 4.0 by getting rid of this so that it's only an instance method. See also TODO in variant_call.cpp
- bool is_equal_approx(const Basis &a, const Basis &b) const { return a.is_equal_approx(b); }
- bool is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon = UNIT_EPSILON) const;
bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
@@ -234,7 +235,9 @@ public:
void orthonormalize();
Basis orthonormalized() const;
+#ifdef MATH_CHECKS
bool is_symmetric() const;
+#endif
Basis diagonalize();
operator Quat() const { return get_quat(); }
@@ -254,17 +257,7 @@ public:
elements[2] = row2;
}
- _FORCE_INLINE_ Basis() {
- elements[0][0] = 1;
- elements[0][1] = 0;
- elements[0][2] = 0;
- elements[1][0] = 0;
- elements[1][1] = 1;
- elements[1][2] = 0;
- elements[2][0] = 0;
- elements[2][1] = 0;
- elements[2][2] = 1;
- }
+ _FORCE_INLINE_ Basis() {}
};
_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 735a30f6cc..1040f9e0e4 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -596,7 +596,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case TEXT_CHAR: {
- CharType result[2] = { *p_inputs[0], 0 };
+ char32_t result[2] = { *p_inputs[0], 0 };
*r_return = String(result);
@@ -739,7 +739,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
////////
-static bool _is_number(CharType c) {
+static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
}
@@ -747,7 +747,7 @@ Error Expression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
- CharType cchar = GET_CHAR();
+ char32_t cchar = GET_CHAR();
switch (cchar) {
case 0: {
@@ -900,7 +900,7 @@ Error Expression::_get_token(Token &r_token) {
case '"': {
String str;
while (true) {
- CharType ch = GET_CHAR();
+ char32_t ch = GET_CHAR();
if (ch == 0) {
_set_error("Unterminated String");
@@ -912,13 +912,13 @@ Error Expression::_get_token(Token &r_token) {
} else if (ch == '\\') {
//escaped characters...
- CharType next = GET_CHAR();
+ char32_t next = GET_CHAR();
if (next == 0) {
_set_error("Unterminated String");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -939,7 +939,7 @@ Error Expression::_get_token(Token &r_token) {
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
- CharType c = GET_CHAR();
+ char32_t c = GET_CHAR();
if (c == 0) {
_set_error("Unterminated String");
@@ -951,7 +951,7 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType v;
+ char32_t v;
if (_is_number(c)) {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -992,7 +992,7 @@ Error Expression::_get_token(Token &r_token) {
break;
}
- CharType next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
+ char32_t next_char = (str_ofs >= expression.length()) ? 0 : expression[str_ofs];
if (_is_number(cchar) || (cchar == '.' && _is_number(next_char))) {
//a number
@@ -1004,7 +1004,7 @@ Error Expression::_get_token(Token &r_token) {
#define READING_DONE 4
int reading = READING_INT;
- CharType c = cchar;
+ char32_t c = cchar;
bool exp_sign = false;
bool exp_beg = false;
bool is_float = false;
diff --git a/core/math/expression.h b/core/math/expression.h
index 59a9a2f4ed..f2cfe6b1a6 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -343,7 +343,7 @@ protected:
public:
Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>());
- Variant execute(Array p_inputs, Object *p_base = nullptr, bool p_show_error = true);
+ Variant execute(Array p_inputs = Array(), Object *p_base = nullptr, bool p_show_error = true);
bool has_execute_failed() const;
String get_error_text() const;
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 9f8d4da5b3..f83ee44f4a 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -46,7 +46,8 @@ class Math {
public:
Math() {} // useless to instance
- static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
+ // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD).
+ static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF;
static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); }
static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); }
@@ -283,25 +284,13 @@ public:
static void randomize();
static uint32_t rand_from_seed(uint64_t *seed);
static uint32_t rand();
- static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; }
- static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
+ static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
static double random(double from, double to);
static float random(float from, float to);
static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); }
- static _ALWAYS_INLINE_ bool is_equal_approx_ratio(real_t a, real_t b, real_t epsilon = CMP_EPSILON, real_t min_epsilon = CMP_EPSILON) {
- // this is an approximate way to check that numbers are close, as a ratio of their average size
- // helps compare approximate numbers that may be very big or very small
- real_t diff = abs(a - b);
- if (diff == 0.0 || diff < min_epsilon) {
- return true;
- }
- real_t avg_size = (abs(a) + abs(b)) / 2.0;
- diff /= avg_size;
- return diff < epsilon;
- }
-
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) {
diff --git a/core/math/quat.h b/core/math/quat.h
index 64d0f00912..8619ea3c5c 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -130,7 +130,7 @@ public:
w(q.w) {
}
- Quat operator=(const Quat &q) {
+ Quat &operator=(const Quat &q) {
x = q.x;
y = q.y;
z = q.z;
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index 8fd5a056fa..09b13ab74d 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -31,12 +31,12 @@
#ifndef RANDOM_PCG_H
#define RANDOM_PCG_H
-#include <math.h>
-
#include "core/math/math_defs.h"
#include "thirdparty/misc/pcg.h"
+#include <math.h>
+
#if defined(__GNUC__)
#define CLZ32(x) __builtin_clz(x)
#elif defined(_MSC_VER)
@@ -67,7 +67,6 @@ class RandomPCG {
public:
static const uint64_t DEFAULT_SEED = 12047754176567800795U;
static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64;
- static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
RandomPCG(uint64_t p_seed = DEFAULT_SEED, uint64_t p_inc = DEFAULT_INC);
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 8a08d3bf64..0966d3392f 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -114,10 +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 x == p_vec2.x ? (y < p_vec2.y) : (x < p_vec2.x); }
+ bool operator>(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y > p_vec2.y) : (x > p_vec2.x); }
+ bool operator<=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator>=(const Vector2 &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 0bc1a467f2..5370b297f1 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -322,8 +322,8 @@ 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)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z < p_v.z;
} else {
return y < p_v.y;
@@ -334,8 +334,8 @@ 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)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z > p_v.z;
} else {
return y > p_v.y;
@@ -346,8 +346,8 @@ 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)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z <= p_v.z;
} else {
return y < p_v.y;
@@ -358,8 +358,8 @@ 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)) {
+ if (x == p_v.x) {
+ if (y == p_v.y) {
return z >= p_v.z;
} else {
return y > p_v.y;
diff --git a/core/message_queue.h b/core/message_queue.h
index 7d13e26208..710a605371 100644
--- a/core/message_queue.h
+++ b/core/message_queue.h
@@ -38,8 +38,7 @@ class MessageQueue {
_THREAD_SAFE_CLASS_
enum {
-
- DEFAULT_QUEUE_SIZE_KB = 1024
+ DEFAULT_QUEUE_SIZE_KB = 4096
};
enum {
diff --git a/core/method_bind.h b/core/method_bind.h
index ff2c771f81..942e2e0036 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -181,18 +181,18 @@ VARIANT_ENUM_CAST(Variant::Type);
VARIANT_ENUM_CAST(Variant::Operator);
template <>
-struct VariantCaster<wchar_t> {
- static _FORCE_INLINE_ wchar_t cast(const Variant &p_variant) {
- return (wchar_t)p_variant.operator int();
+struct VariantCaster<char32_t> {
+ static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
+ return (char32_t)p_variant.operator int();
}
};
#ifdef PTRCALL_ENABLED
template <>
-struct PtrToArg<wchar_t> {
- _FORCE_INLINE_ static wchar_t convert(const void *p_ptr) {
- return wchar_t(*reinterpret_cast<const int *>(p_ptr));
+struct PtrToArg<char32_t> {
+ _FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
+ return char32_t(*reinterpret_cast<const int *>(p_ptr));
}
- _FORCE_INLINE_ static void encode(wchar_t p_val, const void *p_ptr) {
+ _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
*(int *)p_ptr = p_val;
}
};
diff --git a/core/object.h b/core/object.h
index f9a12da8f6..12ef600dfc 100644
--- a/core/object.h
+++ b/core/object.h
@@ -658,7 +658,7 @@ public:
Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper
void notification(int p_notification, bool p_reversed = false);
- String to_string();
+ virtual String to_string();
//used mainly by script, get and set all INCLUDING string
virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const;
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 20b3435911..9dbb2952f7 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -234,7 +234,7 @@ double FileAccess::get_double() const {
String FileAccess::get_token() const {
CharString token;
- CharType c = get_8();
+ char32_t c = get_8();
while (!eof_reached()) {
if (c <= ' ') {
@@ -299,7 +299,7 @@ public:
String FileAccess::get_line() const {
CharBuffer line;
- CharType c = get_8();
+ char32_t c = get_8();
while (!eof_reached()) {
if (c == '\n' || c == '\0') {
@@ -342,8 +342,8 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
bool in_quote = false;
String current;
for (int i = 0; i < l.length(); i++) {
- CharType c = l[i];
- CharType s[2] = { 0, 0 };
+ char32_t c = l[i];
+ char32_t s[2] = { 0, 0 };
if (!in_quote && c == p_delim[0]) {
strings.push_back(current);
diff --git a/core/os/os.cpp b/core/os/os.cpp
index dc8bd5ee69..3a398316bd 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -80,10 +80,6 @@ String OS::get_iso_date_time(bool local) const {
timezone;
}
-uint64_t OS::get_splash_tick_msec() const {
- return _msec_splash;
-}
-
double OS::get_unix_time() const {
return 0;
}
diff --git a/core/os/os.h b/core/os/os.h
index 48dae99188..4c1d930107 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -52,7 +52,6 @@ class OS {
bool _verbose_stdout = false;
bool _debug_stdout = false;
String _local_clipboard;
- uint64_t _msec_splash;
bool _no_window = false;
int _exit_code = 0;
int _orientation;
@@ -86,11 +85,13 @@ public:
protected:
friend class Main;
+ // Needed by tests to setup command-line args.
+ friend int test_main(int argc, char *argv[]);
HasServerFeatureCallback has_server_feature_callback = nullptr;
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
- // functions used by main to initialize/deinitialize the OS
+ // Functions used by Main to initialize/deinitialize the OS.
void add_logger(Logger *p_logger);
virtual void initialize() = 0;
@@ -218,7 +219,6 @@ public:
virtual uint64_t get_ticks_usec() const = 0;
uint32_t get_ticks_msec() const;
- uint64_t get_splash_tick_msec() const;
virtual bool is_userfs_persistent() const { return true; }
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 960a0ec1b0..efe13e740d 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -291,12 +291,12 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files) {
+bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset) {
if (PackedData::get_singleton()->is_disabled()) {
return false;
}
- bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files) == OK;
+ bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_offset) == OK;
if (!ok) {
return false;
@@ -1030,7 +1030,7 @@ void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
- ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files"), &ProjectSettings::_load_resource_pack, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "offset"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(0));
ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert);
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert);
diff --git a/core/project_settings.h b/core/project_settings.h
index 70b54ec854..29b2406dd2 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -107,7 +107,7 @@ protected:
void _convert_to_last_version(int p_from_version);
- bool _load_resource_pack(const String &p_pack, bool p_replace_files = true);
+ bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0);
void _add_property_info_bind(const Dictionary &p_info);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 4f094dd6c6..a2b3f75bea 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -232,7 +232,7 @@ void register_core_types() {
}
void register_core_settings() {
- //since in register core types, globals may not e present
+ // Since in register core types, globals may not be present.
GLOBAL_DEF("network/limits/tcp/connect_timeout_seconds", (30));
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1"));
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
diff --git a/core/string_buffer.h b/core/string_buffer.h
index f9cf31075a..a685720851 100644
--- a/core/string_buffer.h
+++ b/core/string_buffer.h
@@ -35,21 +35,21 @@
template <int SHORT_BUFFER_SIZE = 64>
class StringBuffer {
- CharType short_buffer[SHORT_BUFFER_SIZE];
+ char32_t short_buffer[SHORT_BUFFER_SIZE];
String buffer;
int string_length = 0;
- _FORCE_INLINE_ CharType *current_buffer_ptr() {
+ _FORCE_INLINE_ char32_t *current_buffer_ptr() {
return static_cast<String &>(buffer).empty() ? short_buffer : buffer.ptrw();
}
public:
- StringBuffer &append(CharType p_char);
+ StringBuffer &append(char32_t p_char);
StringBuffer &append(const String &p_string);
StringBuffer &append(const char *p_str);
- StringBuffer &append(const CharType *p_str, int p_clip_to_len = -1);
+ StringBuffer &append(const char32_t *p_str, int p_clip_to_len = -1);
- _FORCE_INLINE_ void operator+=(CharType p_char) {
+ _FORCE_INLINE_ void operator+=(char32_t p_char) {
append(p_char);
}
@@ -61,7 +61,7 @@ public:
append(p_str);
}
- _FORCE_INLINE_ void operator+=(const CharType *p_str) {
+ _FORCE_INLINE_ void operator+=(const char32_t *p_str) {
append(p_str);
}
@@ -80,7 +80,7 @@ public:
};
template <int SHORT_BUFFER_SIZE>
-StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(CharType p_char) {
+StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(char32_t p_char) {
reserve(string_length + 2);
current_buffer_ptr()[string_length++] = p_char;
return *this;
@@ -88,7 +88,7 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(CharTyp
template <int SHORT_BUFFER_SIZE>
StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const String &p_string) {
- return append(p_string.c_str());
+ return append(p_string.get_data());
}
template <int SHORT_BUFFER_SIZE>
@@ -96,7 +96,7 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const c
int len = strlen(p_str);
reserve(string_length + len + 1);
- CharType *buf = current_buffer_ptr();
+ char32_t *buf = current_buffer_ptr();
for (const char *c_ptr = p_str; *c_ptr; ++c_ptr) {
buf[string_length++] = *c_ptr;
}
@@ -104,13 +104,13 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const c
}
template <int SHORT_BUFFER_SIZE>
-StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const CharType *p_str, int p_clip_to_len) {
+StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const char32_t *p_str, int p_clip_to_len) {
int len = 0;
while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) {
++len;
}
reserve(string_length + len + 1);
- memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType));
+ memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(char32_t));
string_length += len;
return *this;
@@ -125,7 +125,7 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::reserve(int p_
bool need_copy = string_length > 0 && buffer.empty();
buffer.resize(next_power_of_2(p_size));
if (need_copy) {
- memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(CharType));
+ memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(char32_t));
}
return *this;
diff --git a/core/string_builder.cpp b/core/string_builder.cpp
index c8d6498f27..dec299ffa3 100644
--- a/core/string_builder.cpp
+++ b/core/string_builder.cpp
@@ -61,7 +61,7 @@ String StringBuilder::as_string() const {
return "";
}
- CharType *buffer = memnew_arr(CharType, string_length);
+ char32_t *buffer = memnew_arr(char32_t, string_length);
int current_position = 0;
@@ -73,7 +73,7 @@ String StringBuilder::as_string() const {
// Godot string
const String &s = strings[godot_string_elem];
- memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType));
+ memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(char32_t));
current_position += s.length();
diff --git a/core/string_name.cpp b/core/string_name.cpp
index cbf6009681..6260e3ce8c 100644
--- a/core/string_name.cpp
+++ b/core/string_name.cpp
@@ -317,7 +317,7 @@ StringName StringName::search(const char *p_name) {
return StringName(); //does not exist
}
-StringName StringName::search(const CharType *p_name) {
+StringName StringName::search(const char32_t *p_name) {
ERR_FAIL_COND_V(!configured, StringName());
ERR_FAIL_COND_V(!p_name, StringName());
diff --git a/core/string_name.h b/core/string_name.h
index 886ddd0ee7..4f90479bda 100644
--- a/core/string_name.h
+++ b/core/string_name.h
@@ -122,7 +122,7 @@ public:
}
static StringName search(const char *p_name);
- static StringName search(const CharType *p_name);
+ static StringName search(const char32_t *p_name);
static StringName search(const String &p_name);
struct AlphCompare {
diff --git a/core/translation_po.h b/core/translation_po.h
index 730635f63d..88830210ef 100644
--- a/core/translation_po.h
+++ b/core/translation_po.h
@@ -42,7 +42,7 @@ class TranslationPO : public Translation {
// TLDR: Maps context to a list of source strings and translated strings. In PO terms, maps msgctxt to a list of msgid and msgstr.
// The first key corresponds to context, and the second key (of the contained HashMap) corresponds to source string.
// The value Vector<StringName> in the second map stores the translated strings. Index 0, 1, 2 matches msgstr[0], msgstr[1], msgstr[2]... in the case of plurals.
- // Otherwise index 0 mathes to msgstr in a singular translation.
+ // Otherwise index 0 matches to msgstr in a singular translation.
// Strings without context have "" as first key.
HashMap<StringName, HashMap<StringName, Vector<StringName>>> translation_map;
diff --git a/core/type_info.h b/core/type_info.h
index e3d2b5bd53..3c7f59bb84 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -132,7 +132,8 @@ MAKE_TYPE_INFO_WITH_META(uint32_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_
MAKE_TYPE_INFO_WITH_META(int32_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT32)
MAKE_TYPE_INFO_WITH_META(uint64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT64)
MAKE_TYPE_INFO_WITH_META(int64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT64)
-MAKE_TYPE_INFO(wchar_t, Variant::INT)
+MAKE_TYPE_INFO(char16_t, Variant::INT)
+MAKE_TYPE_INFO(char32_t, Variant::INT)
MAKE_TYPE_INFO_WITH_META(float, Variant::FLOAT, GodotTypeInfo::METADATA_REAL_IS_FLOAT)
MAKE_TYPE_INFO_WITH_META(double, Variant::FLOAT, GodotTypeInfo::METADATA_REAL_IS_DOUBLE)
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 9d2d938eaf..d5afbc2b47 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -39,7 +39,6 @@
#include "core/ucaps.h"
#include "core/variant.h"
-#include <wchar.h>
#include <cstdint>
#ifndef NO_USE_STDLIB
@@ -62,9 +61,10 @@
#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
const char CharString::_null = 0;
-const CharType String::_null = 0;
+const char16_t Char16String::_null = 0;
+const char32_t String::_null = 0;
-bool is_symbol(CharType c) {
+bool is_symbol(char32_t c) {
return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
}
@@ -96,9 +96,11 @@ bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
}
}
-/** STRING **/
+/*************************************************************************/
+/* Char16String */
+/*************************************************************************/
-bool CharString::operator<(const CharString &p_right) const {
+bool Char16String::operator<(const Char16String &p_right) const {
if (length() == 0) {
return p_right.length() != 0;
}
@@ -106,7 +108,7 @@ bool CharString::operator<(const CharString &p_right) const {
return is_str_less(get_data(), p_right.get_data());
}
-CharString &CharString::operator+=(char p_char) {
+Char16String &Char16String::operator+=(char16_t p_char) {
resize(size() ? size() + 1 : 2);
set(length(), 0);
set(length() - 1, p_char);
@@ -114,19 +116,75 @@ CharString &CharString::operator+=(char p_char) {
return *this;
}
-const char *CharString::get_data() const {
+Char16String &Char16String::operator=(const char16_t *p_cstr) {
+ copy_from(p_cstr);
+ return *this;
+}
+
+const char16_t *Char16String::get_data() const {
if (size()) {
return &operator[](0);
} else {
- return "";
+ return u"";
}
}
+void Char16String::copy_from(const char16_t *p_cstr) {
+ if (!p_cstr) {
+ resize(0);
+ return;
+ }
+
+ const char16_t *s = p_cstr;
+ for (; *s; s++) {
+ }
+ size_t len = s - p_cstr;
+
+ if (len == 0) {
+ resize(0);
+ return;
+ }
+
+ Error err = resize(++len); // include terminating null char
+
+ ERR_FAIL_COND_MSG(err != OK, "Failed to copy char16_t string.");
+
+ memcpy(ptrw(), p_cstr, len * sizeof(char16_t));
+}
+
+/*************************************************************************/
+/* CharString */
+/*************************************************************************/
+
+bool CharString::operator<(const CharString &p_right) const {
+ if (length() == 0) {
+ return p_right.length() != 0;
+ }
+
+ return is_str_less(get_data(), p_right.get_data());
+}
+
+CharString &CharString::operator+=(char p_char) {
+ resize(size() ? size() + 1 : 2);
+ set(length(), 0);
+ set(length() - 1, p_char);
+
+ return *this;
+}
+
CharString &CharString::operator=(const char *p_cstr) {
copy_from(p_cstr);
return *this;
}
+const char *CharString::get_data() const {
+ if (size()) {
+ return &operator[](0);
+ } else {
+ return "";
+ }
+}
+
void CharString::copy_from(const char *p_cstr) {
if (!p_cstr) {
resize(0);
@@ -147,7 +205,44 @@ void CharString::copy_from(const char *p_cstr) {
memcpy(ptrw(), p_cstr, len);
}
+/*************************************************************************/
+/* String */
+/*************************************************************************/
+
+//TODO: move to TextServer
+//kind of poor should be rewritten properly
+String String::word_wrap(int p_chars_per_line) const {
+ int from = 0;
+ int last_space = 0;
+ String ret;
+ for (int i = 0; i < length(); i++) {
+ if (i - from >= p_chars_per_line) {
+ if (last_space == -1) {
+ ret += substr(from, i - from + 1) + "\n";
+ } else {
+ ret += substr(from, last_space - from) + "\n";
+ i = last_space; //rewind
+ }
+ from = i + 1;
+ last_space = -1;
+ } else if (operator[](i) == ' ' || operator[](i) == '\t') {
+ last_space = i;
+ } else if (operator[](i) == '\n') {
+ ret += substr(from, i - from) + "\n";
+ from = i + 1;
+ last_space = -1;
+ }
+ }
+
+ if (from < length()) {
+ ret += substr(from, length());
+ }
+
+ return ret;
+}
+
void String::copy_from(const char *p_cstr) {
+ // copy Latin-1 encoded c-string directly
if (!p_cstr) {
resize(0);
return;
@@ -166,21 +261,22 @@ void String::copy_from(const char *p_cstr) {
resize(len + 1); // include 0
- CharType *dst = this->ptrw();
+ char32_t *dst = this->ptrw();
for (int i = 0; i < len + 1; i++) {
dst[i] = p_cstr[i];
}
}
-void String::copy_from(const CharType *p_cstr, const int p_clip_to) {
+void String::copy_from(const char *p_cstr, const int p_clip_to) {
+ // copy Latin-1 encoded c-string directly
if (!p_cstr) {
resize(0);
return;
}
int len = 0;
- const CharType *ptr = p_cstr;
+ const char *ptr = p_cstr;
while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0) {
len++;
}
@@ -190,55 +286,117 @@ void String::copy_from(const CharType *p_cstr, const int p_clip_to) {
return;
}
- copy_from_unchecked(p_cstr, len);
-}
-
-// assumes the following have already been validated:
-// p_char != nullptr
-// p_length > 0
-// p_length <= p_char strlen
-void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
- resize(p_length + 1);
- set(p_length, 0);
+ resize(len + 1); // include 0
- CharType *dst = ptrw();
+ char32_t *dst = this->ptrw();
- for (int i = 0; i < p_length; i++) {
- dst[i] = p_char[i];
+ for (int i = 0; i < len; i++) {
+ dst[i] = p_cstr[i];
}
+ dst[len] = 0;
}
-void String::copy_from(const CharType &p_char) {
+void String::copy_from(const wchar_t *p_cstr) {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit, parse as UTF-16
+ parse_utf16((const char16_t *)p_cstr);
+#else
+ // wchar_t is 32-bit, copy directly
+ copy_from((const char32_t *)p_cstr);
+#endif
+}
+
+void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit, parse as UTF-16
+ parse_utf16((const char16_t *)p_cstr, p_clip_to);
+#else
+ // wchar_t is 32-bit, copy directly
+ copy_from((const char32_t *)p_cstr, p_clip_to);
+#endif
+}
+
+void String::copy_from(const char32_t &p_char) {
resize(2);
- set(0, p_char);
+ if ((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff)) {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char, 16) + ".");
+ set(0, 0xfffd);
+ } else {
+ set(0, p_char);
+ }
set(1, 0);
}
-bool String::operator==(const String &p_str) const {
- if (length() != p_str.length()) {
- return false;
+void String::copy_from(const char32_t *p_cstr) {
+ if (!p_cstr) {
+ resize(0);
+ return;
}
- if (empty()) {
- return true;
+
+ int len = 0;
+ const char32_t *ptr = p_cstr;
+ while (*(ptr++) != 0) {
+ len++;
}
- int l = length();
+ if (len == 0) {
+ resize(0);
+ return;
+ }
- const CharType *src = c_str();
- const CharType *dst = p_str.c_str();
+ copy_from_unchecked(p_cstr, len);
+}
- /* Compare char by char */
- for (int i = 0; i < l; i++) {
- if (src[i] != dst[i]) {
- return false;
+void String::copy_from(const char32_t *p_cstr, const int p_clip_to) {
+ if (!p_cstr) {
+ resize(0);
+ return;
+ }
+
+ int len = 0;
+ const char32_t *ptr = p_cstr;
+ while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0) {
+ len++;
+ }
+
+ if (len == 0) {
+ resize(0);
+ return;
+ }
+
+ copy_from_unchecked(p_cstr, len);
+}
+
+// assumes the following have already been validated:
+// p_char != nullptr
+// p_length > 0
+// p_length <= p_char strlen
+void String::copy_from_unchecked(const char32_t *p_char, const int p_length) {
+ resize(p_length + 1);
+ set(p_length, 0);
+
+ char32_t *dst = ptrw();
+
+ for (int i = 0; i < p_length; i++) {
+ if ((p_char[i] >= 0xd800 && p_char[i] <= 0xdfff) || (p_char[i] > 0x10ffff)) {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char[i], 16) + ".");
+ dst[i] = 0xfffd;
+ } else {
+ dst[i] = p_char[i];
}
}
+}
- return true;
+void String::operator=(const char *p_str) {
+ copy_from(p_str);
}
-bool String::operator!=(const String &p_str) const {
- return !(*this == p_str);
+void String::operator=(const char32_t *p_str) {
+ copy_from(p_str);
+}
+
+void String::operator=(const wchar_t *p_str) {
+ copy_from(p_str);
}
String String::operator+(const String &p_str) const {
@@ -247,6 +405,28 @@ String String::operator+(const String &p_str) const {
return res;
}
+String operator+(const char *p_chr, const String &p_str) {
+ String tmp = p_chr;
+ tmp += p_str;
+ return tmp;
+}
+
+String operator+(const wchar_t *p_chr, const String &p_str) {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit
+ String tmp = String::utf16((const char16_t *)p_chr);
+#else
+ // wchar_t is 32-bi
+ String tmp = (const char32_t *)p_chr;
+#endif
+ tmp += p_str;
+ return tmp;
+}
+
+String operator+(char32_t p_chr, const String &p_str) {
+ return (String::chr(p_chr) + p_str);
+}
+
String &String::operator+=(const String &p_str) {
if (empty()) {
*this = p_str;
@@ -261,8 +441,8 @@ String &String::operator+=(const String &p_str) {
resize(length() + p_str.size());
- const CharType *src = p_str.c_str();
- CharType *dst = ptrw();
+ const char32_t *src = p_str.get_data();
+ char32_t *dst = ptrw();
set(length(), 0);
@@ -273,19 +453,6 @@ String &String::operator+=(const String &p_str) {
return *this;
}
-String &String::operator+=(const CharType *p_str) {
- *this += String(p_str);
- return *this;
-}
-
-String &String::operator+=(CharType p_char) {
- resize(size() ? size() + 1 : 2);
- set(length(), 0);
- set(length() - 1, p_char);
-
- return *this;
-}
-
String &String::operator+=(const char *p_str) {
if (!p_str || p_str[0] == 0) {
return *this;
@@ -301,7 +468,7 @@ String &String::operator+=(const char *p_str) {
resize(from + src_len + 1);
- CharType *dst = ptrw();
+ char32_t *dst = ptrw();
set(length(), 0);
@@ -312,16 +479,43 @@ String &String::operator+=(const char *p_str) {
return *this;
}
-void String::operator=(const char *p_str) {
- copy_from(p_str);
+String &String::operator+=(const wchar_t *p_str) {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit
+ *this += String::utf16((const char16_t *)p_str);
+#else
+ // wchar_t is 32-bit
+ *this += String((const char32_t *)p_str);
+#endif
+ return *this;
}
-void String::operator=(const CharType *p_str) {
- copy_from(p_str);
+String &String::operator+=(const char32_t *p_str) {
+ *this += String(p_str);
+ return *this;
}
-bool String::operator==(const StrRange &p_str_range) const {
- int len = p_str_range.len;
+String &String::operator+=(char32_t p_char) {
+ resize(size() ? size() + 1 : 2);
+ set(length(), 0);
+ if ((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff)) {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(p_char, 16) + ".");
+ set(length() - 1, 0xfffd);
+ } else {
+ set(length() - 1, p_char);
+ }
+
+ return *this;
+}
+
+bool String::operator==(const char *p_str) const {
+ // compare Latin-1 encoded c-string
+ int len = 0;
+ const char *aux = p_str;
+
+ while (*(aux++) != 0) {
+ len++;
+ }
if (length() != len) {
return false;
@@ -330,12 +524,13 @@ bool String::operator==(const StrRange &p_str_range) const {
return true;
}
- const CharType *c_str = p_str_range.c_str;
- const CharType *dst = &operator[](0);
+ int l = length();
- /* Compare char by char */
- for (int i = 0; i < len; i++) {
- if (c_str[i] != dst[i]) {
+ const char32_t *dst = get_data();
+
+ // Compare char by char
+ for (int i = 0; i < l; i++) {
+ if ((char32_t)p_str[i] != dst[i]) {
return false;
}
}
@@ -343,9 +538,19 @@ bool String::operator==(const StrRange &p_str_range) const {
return true;
}
-bool String::operator==(const char *p_str) const {
+bool String::operator==(const wchar_t *p_str) const {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit, parse as UTF-16
+ return *this == String::utf16((const char16_t *)p_str);
+#else
+ // wchar_t is 32-bit, compare char by char
+ return *this == (const char32_t *)p_str;
+#endif
+}
+
+bool String::operator==(const char32_t *p_str) const {
int len = 0;
- const char *aux = p_str;
+ const char32_t *aux = p_str;
while (*(aux++) != 0) {
len++;
@@ -360,7 +565,7 @@ bool String::operator==(const char *p_str) const {
int l = length();
- const CharType *dst = c_str();
+ const char32_t *dst = get_data();
/* Compare char by char */
for (int i = 0; i < l; i++) {
@@ -372,14 +577,32 @@ bool String::operator==(const char *p_str) const {
return true;
}
-bool String::operator==(const CharType *p_str) const {
- int len = 0;
- const CharType *aux = p_str;
+bool String::operator==(const String &p_str) const {
+ if (length() != p_str.length()) {
+ return false;
+ }
+ if (empty()) {
+ return true;
+ }
- while (*(aux++) != 0) {
- len++;
+ int l = length();
+
+ const char32_t *src = get_data();
+ const char32_t *dst = p_str.get_data();
+
+ /* Compare char by char */
+ for (int i = 0; i < l; i++) {
+ if (src[i] != dst[i]) {
+ return false;
+ }
}
+ return true;
+}
+
+bool String::operator==(const StrRange &p_str_range) const {
+ int len = p_str_range.len;
+
if (length() != len) {
return false;
}
@@ -387,13 +610,12 @@ bool String::operator==(const CharType *p_str) const {
return true;
}
- int l = length();
-
- const CharType *dst = c_str();
+ const char32_t *c_str = p_str_range.c_str;
+ const char32_t *dst = &operator[](0);
/* Compare char by char */
- for (int i = 0; i < l; i++) {
- if (p_str[i] != dst[i]) {
+ for (int i = 0; i < len; i++) {
+ if (c_str[i] != dst[i]) {
return false;
}
}
@@ -401,30 +623,68 @@ bool String::operator==(const CharType *p_str) const {
return true;
}
+bool operator==(const char *p_chr, const String &p_str) {
+ return p_str == p_chr;
+}
+
+bool operator==(const wchar_t *p_chr, const String &p_str) {
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit
+ return p_str == String::utf16((const char16_t *)p_chr);
+#else
+ // wchar_t is 32-bi
+ return p_str == String((const char32_t *)p_chr);
+#endif
+}
+
bool String::operator!=(const char *p_str) const {
return (!(*this == p_str));
}
-bool String::operator!=(const CharType *p_str) const {
+bool String::operator!=(const wchar_t *p_str) const {
return (!(*this == p_str));
}
-bool String::operator<(const CharType *p_str) const {
+bool String::operator!=(const char32_t *p_str) const {
+ return (!(*this == p_str));
+}
+
+bool String::operator!=(const String &p_str) const {
+ return !((*this == p_str));
+}
+
+bool String::operator<=(const String &p_str) const {
+ return (*this < p_str) || (*this == p_str);
+}
+
+bool String::operator<(const char *p_str) const {
if (empty() && p_str[0] == 0) {
return false;
}
if (empty()) {
return true;
}
-
- return is_str_less(c_str(), p_str);
+ return is_str_less(get_data(), p_str);
}
-bool String::operator<=(const String &p_str) const {
- return (*this < p_str) || (*this == p_str);
+bool String::operator<(const wchar_t *p_str) const {
+ if (empty() && p_str[0] == 0) {
+ return false;
+ }
+ if (empty()) {
+ return true;
+ }
+
+#ifdef WINDOWS_ENABLED
+ // wchar_t is 16-bit
+ return is_str_less(get_data(), String::utf16((const char16_t *)p_str).get_data());
+#else
+ // wchar_t is 32-bit
+ return is_str_less(get_data(), (const char32_t *)p_str);
+#endif
}
-bool String::operator<(const char *p_str) const {
+bool String::operator<(const char32_t *p_str) const {
if (empty() && p_str[0] == 0) {
return false;
}
@@ -432,11 +692,11 @@ bool String::operator<(const char *p_str) const {
return true;
}
- return is_str_less(c_str(), p_str);
+ return is_str_less(get_data(), p_str);
}
bool String::operator<(const String &p_str) const {
- return operator<(p_str.c_str());
+ return operator<(p_str.get_data());
}
signed char String::nocasecmp_to(const String &p_str) const {
@@ -450,8 +710,8 @@ signed char String::nocasecmp_to(const String &p_str) const {
return 1;
}
- const CharType *that_str = p_str.c_str();
- const CharType *this_str = c_str();
+ const char32_t *that_str = p_str.get_data();
+ const char32_t *this_str = get_data();
while (true) {
if (*that_str == 0 && *this_str == 0) {
@@ -482,8 +742,8 @@ signed char String::casecmp_to(const String &p_str) const {
return 1;
}
- const CharType *that_str = p_str.c_str();
- const CharType *this_str = c_str();
+ const char32_t *that_str = p_str.get_data();
+ const char32_t *this_str = get_data();
while (true) {
if (*that_str == 0 && *this_str == 0) {
@@ -504,8 +764,8 @@ signed char String::casecmp_to(const String &p_str) const {
}
signed char String::naturalnocasecmp_to(const String &p_str) const {
- const CharType *this_str = c_str();
- const CharType *that_str = p_str.c_str();
+ const char32_t *this_str = get_data();
+ const char32_t *that_str = p_str.get_data();
if (this_str && that_str) {
while (*this_str == '.' || *that_str == '.') {
@@ -571,6 +831,11 @@ signed char String::naturalnocasecmp_to(const String &p_str) const {
return 0;
}
+const char32_t *String::get_data() const {
+ static const char32_t zero = 0;
+ return size() ? &operator[](0) : &zero;
+}
+
void String::erase(int p_pos, int p_chars) {
*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
}
@@ -593,7 +858,7 @@ String String::capitalize() const {
}
String String::camelcase_to_underscore(bool lowercase) const {
- const CharType *cstr = c_str();
+ const char32_t *cstr = get_data();
String new_string;
const char A = 'A', Z = 'Z';
const char a = 'a', z = 'z';
@@ -705,7 +970,7 @@ String String::get_slice(String p_splitter, int p_slice) const {
return ""; //no find!
}
-String String::get_slicec(CharType p_splitter, int p_slice) const {
+String String::get_slicec(char32_t p_splitter, int p_slice) const {
if (empty()) {
return String();
}
@@ -714,7 +979,7 @@ String String::get_slicec(CharType p_splitter, int p_slice) const {
return String();
}
- const CharType *c = this->ptr();
+ const char32_t *c = this->ptr();
int i = 0;
int prev = 0;
int count = 0;
@@ -851,7 +1116,7 @@ Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty)
end = len;
}
if (p_allow_empty || (end > from)) {
- ret.push_back(String::to_float(&c_str()[from]));
+ ret.push_back(String::to_float(&get_data()[from]));
}
if (end == len) {
@@ -880,7 +1145,7 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
}
if (p_allow_empty || (end > from)) {
- ret.push_back(String::to_float(&c_str()[from]));
+ ret.push_back(String::to_float(&get_data()[from]));
}
if (end == len) {
@@ -904,7 +1169,7 @@ Vector<int> String::split_ints(const String &p_splitter, bool p_allow_empty) con
end = len;
}
if (p_allow_empty || (end > from)) {
- ret.push_back(String::to_int(&c_str()[from], end - from));
+ ret.push_back(String::to_int(&get_data()[from], end - from));
}
if (end == len) {
@@ -933,7 +1198,7 @@ Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allo
}
if (p_allow_empty || (end > from)) {
- ret.push_back(String::to_int(&c_str()[from], end - from));
+ ret.push_back(String::to_int(&get_data()[from], end - from));
}
if (end == len) {
@@ -946,7 +1211,7 @@ Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allo
return ret;
}
-String String::join(Vector<String> parts) {
+String String::join(Vector<String> parts) const {
String ret;
for (int i = 0; i < parts.size(); ++i) {
if (i > 0) {
@@ -957,11 +1222,11 @@ String String::join(Vector<String> parts) {
return ret;
}
-CharType String::char_uppercase(CharType p_char) {
+char32_t String::char_uppercase(char32_t p_char) {
return _find_upper(p_char);
}
-CharType String::char_lowercase(CharType p_char) {
+char32_t String::char_lowercase(char32_t p_char) {
return _find_lower(p_char);
}
@@ -969,8 +1234,8 @@ String String::to_upper() const {
String upper = *this;
for (int i = 0; i < upper.size(); i++) {
- const CharType s = upper[i];
- const CharType t = _find_upper(s);
+ const char32_t s = upper[i];
+ const char32_t t = _find_upper(s);
if (s != t) { // avoid copy on write
upper[i] = t;
}
@@ -983,8 +1248,8 @@ String String::to_lower() const {
String lower = *this;
for (int i = 0; i < lower.size(); i++) {
- const CharType s = lower[i];
- const CharType t = _find_lower(s);
+ const char32_t s = lower[i];
+ const char32_t t = _find_lower(s);
if (s != t) { // avoid copy on write
lower[i] = t;
}
@@ -993,34 +1258,8 @@ String String::to_lower() const {
return lower;
}
-const CharType *String::c_str() const {
- static const CharType zero = 0;
-
- return size() ? &operator[](0) : &zero;
-}
-
-String String::md5(const uint8_t *p_md5) {
- return String::hex_encode_buffer(p_md5, 16);
-}
-
-String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
- static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
- String ret;
- char v[2] = { 0, 0 };
-
- for (int i = 0; i < p_len; i++) {
- v[0] = hex[p_buffer[i] >> 4];
- ret += v;
- v[0] = hex[p_buffer[i] & 0xF];
- ret += v;
- }
-
- return ret;
-}
-
-String String::chr(CharType p_char) {
- CharType c[2] = { p_char, 0 };
+String String::chr(char32_t p_char) {
+ char32_t c[2] = { p_char, 0 };
return String(c);
}
@@ -1028,6 +1267,14 @@ String String::num(double p_num, int p_decimals) {
if (Math::is_nan(p_num)) {
return "nan";
}
+
+ if (Math::is_inf(p_num)) {
+ if (signbit(p_num)) {
+ return "-inf";
+ } else {
+ return "inf";
+ }
+ }
#ifndef NO_USE_STDLIB
if (p_decimals > 16) {
@@ -1106,7 +1353,7 @@ String String::num(double p_num, int p_decimals) {
/* decimal part */
if (p_decimals > 0 || (p_decimals == -1 && (int)p_num != p_num)) {
- double dec = p_num - (float)((int)p_num);
+ double dec = p_num - (double)((int)p_num);
int digit = 0;
if (p_decimals > MAX_DIGITS)
@@ -1125,7 +1372,7 @@ String String::num(double p_num, int p_decimals) {
if (digit == MAX_DIGITS) //no point in going to infinite
break;
- if ((dec - (float)((int)dec)) < 1e-6)
+ if ((dec - (double)((int)dec)) < 1e-6)
break;
}
@@ -1159,7 +1406,7 @@ String String::num(double p_num, int p_decimals) {
s = "0";
else {
while (intn) {
- CharType num = '0' + (intn % 10);
+ char32_t num = '0' + (intn % 10);
intn /= 10;
s = num + s;
}
@@ -1188,7 +1435,7 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
}
String s;
s.resize(chars + 1);
- CharType *c = s.ptrw();
+ char32_t *c = s.ptrw();
c[chars] = 0;
n = p_num;
do {
@@ -1221,7 +1468,7 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
String s;
s.resize(chars + 1);
- CharType *c = s.ptrw();
+ char32_t *c = s.ptrw();
c[chars] = 0;
n = p_num;
do {
@@ -1240,6 +1487,18 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
}
String String::num_real(double p_num) {
+ if (Math::is_nan(p_num)) {
+ return "nan";
+ }
+
+ if (Math::is_inf(p_num)) {
+ if (signbit(p_num)) {
+ return "-inf";
+ } else {
+ return "inf";
+ }
+ }
+
String s;
String sd;
/* integer part */
@@ -1251,7 +1510,7 @@ String String::num_real(double p_num) {
/* decimal part */
if ((int)p_num != p_num) {
- double dec = p_num - (float)((int)p_num);
+ double dec = p_num - (double)((int)p_num);
int digit = 0;
int decimals = MAX_DIGITS;
@@ -1265,7 +1524,7 @@ String String::num_real(double p_num) {
dec_max = dec_max * 10 + 9;
digit++;
- if ((dec - (float)((int)dec)) < 1e-6) {
+ if ((dec - (double)((int)dec)) < 1e-6) {
break;
}
@@ -1302,7 +1561,7 @@ String String::num_real(double p_num) {
s = "0";
} else {
while (intn) {
- CharType num = '0' + (intn % 10);
+ char32_t num = '0' + (intn % 10);
intn /= 10;
s = num + s;
}
@@ -1319,6 +1578,14 @@ String String::num_scientific(double p_num) {
if (Math::is_nan(p_num)) {
return "nan";
}
+
+ if (Math::is_inf(p_num)) {
+ if (signbit(p_num)) {
+ return "-inf";
+ } else {
+ return "inf";
+ }
+ }
#ifndef NO_USE_STDLIB
char buf[256];
@@ -1348,6 +1615,26 @@ String String::num_scientific(double p_num) {
#endif
}
+String String::md5(const uint8_t *p_md5) {
+ return String::hex_encode_buffer(p_md5, 16);
+}
+
+String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
+ static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ String ret;
+ char v[2] = { 0, 0 };
+
+ for (int i = 0; i < p_len; i++) {
+ v[0] = hex[p_buffer[i] >> 4];
+ ret += v;
+ v[0] = hex[p_buffer[i] & 0xF];
+ ret += v;
+ }
+
+ return ret;
+}
+
CharString String::ascii(bool p_allow_extended) const {
if (!length()) {
return CharString();
@@ -1357,7 +1644,13 @@ CharString String::ascii(bool p_allow_extended) const {
cs.resize(size());
for (int i = 0; i < size(); i++) {
- cs[i] = operator[](i);
+ char32_t c = operator[](i);
+ if ((c <= 0x7f) || (c <= 0xff && p_allow_extended)) {
+ cs[i] = c;
+ } else {
+ print_error("Unicode parsing error: Cannot represent " + num_int64(c, 16) + " as ASCII/Latin-1 character.");
+ cs[i] = 0x20;
+ }
}
return cs;
@@ -1371,7 +1664,7 @@ String String::utf8(const char *p_utf8, int p_len) {
}
bool String::parse_utf8(const char *p_utf8, int p_len) {
-#define _UNICERROR(m_err) print_line("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-8?");
+#define _UNICERROR(m_err) print_error("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-8?");
if (!p_utf8) {
return true;
@@ -1384,9 +1677,9 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
/* HANDLE BOM (Byte Order Mark) */
if (p_len < 0 || p_len >= 3) {
- bool has_bom = uint8_t(p_utf8[0]) == 0xEF && uint8_t(p_utf8[1]) == 0xBB && uint8_t(p_utf8[2]) == 0xBF;
+ bool has_bom = uint8_t(p_utf8[0]) == 0xef && uint8_t(p_utf8[1]) == 0xbb && uint8_t(p_utf8[2]) == 0xbf;
if (has_bom) {
- //just skip it
+ //8-bit encoding, byte order has no meaning in UTF-8, just skip it
if (p_len >= 0) {
p_len -= 3;
}
@@ -1405,24 +1698,19 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
/* Determine the number of characters in sequence */
if ((c & 0x80) == 0) {
skip = 0;
- } else if ((c & 0xE0) == 0xC0) {
+ } else if ((c & 0xe0) == 0xc0) {
skip = 1;
- } else if ((c & 0xF0) == 0xE0) {
+ } else if ((c & 0xf0) == 0xe0) {
skip = 2;
- } else if ((c & 0xF8) == 0xF0) {
+ } else if ((c & 0xf8) == 0xf0) {
skip = 3;
- } else if ((c & 0xFC) == 0xF8) {
- skip = 4;
- } else if ((c & 0xFE) == 0xFC) {
- skip = 5;
} else {
- _UNICERROR("invalid skip");
+ _UNICERROR("invalid skip at " + num_int64(cstr_size));
return true; //invalid utf8
}
- if (skip == 1 && (c & 0x1E) == 0) {
- //printf("overlong rejected\n");
- _UNICERROR("overlong rejected");
+ if (skip == 1 && (c & 0x1e) == 0) {
+ _UNICERROR("overlong rejected at " + num_int64(cstr_size));
return true; //reject overlong
}
@@ -1448,7 +1736,7 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
resize(str_size + 1);
- CharType *dst = ptrw();
+ char32_t *dst = ptrw();
dst[str_size] = 0;
while (cstr_size) {
@@ -1457,19 +1745,14 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
/* Determine the number of characters in sequence */
if ((*p_utf8 & 0x80) == 0) {
len = 1;
- } else if ((*p_utf8 & 0xE0) == 0xC0) {
+ } else if ((*p_utf8 & 0xe0) == 0xc0) {
len = 2;
- } else if ((*p_utf8 & 0xF0) == 0xE0) {
+ } else if ((*p_utf8 & 0xf0) == 0xe0) {
len = 3;
- } else if ((*p_utf8 & 0xF8) == 0xF0) {
+ } else if ((*p_utf8 & 0xf8) == 0xf0) {
len = 4;
- } else if ((*p_utf8 & 0xFC) == 0xF8) {
- len = 5;
- } else if ((*p_utf8 & 0xFE) == 0xFC) {
- len = 6;
} else {
_UNICERROR("invalid len");
-
return true; //invalid UTF8
}
@@ -1479,7 +1762,6 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
if (len == 2 && (*p_utf8 & 0x1E) == 0) {
- //printf("overlong rejected\n");
_UNICERROR("no space left");
return true; //reject overlong
}
@@ -1491,24 +1773,23 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
if (len == 1) {
unichar = *p_utf8;
} else {
- unichar = (0xFF >> (len + 1)) & *p_utf8;
+ unichar = (0xff >> (len + 1)) & *p_utf8;
for (int i = 1; i < len; i++) {
- if ((p_utf8[i] & 0xC0) != 0x80) {
+ if ((p_utf8[i] & 0xc0) != 0x80) {
_UNICERROR("invalid utf8");
return true; //invalid utf8
}
- if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7F) >> (7 - len)) == 0) {
+ if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7f) >> (7 - len)) == 0) {
_UNICERROR("invalid utf8 overlong");
return true; //no overlong
}
- unichar = (unichar << 6) | (p_utf8[i] & 0x3F);
+ unichar = (unichar << 6) | (p_utf8[i] & 0x3f);
}
}
-
- //printf("char %i, len %i\n",unichar,len);
- if (sizeof(wchar_t) == 2 && unichar > 0xFFFF) {
- unichar = ' '; //too long for windows
+ if (unichar >= 0xd800 && unichar <= 0xdfff) {
+ _UNICERROR("invalid code point");
+ return CharString();
}
*(dst++) = unichar;
@@ -1517,6 +1798,7 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
return false;
+#undef _UNICERROR
}
CharString String::utf8() const {
@@ -1525,7 +1807,7 @@ CharString String::utf8() const {
return CharString();
}
- const CharType *d = &operator[](0);
+ const char32_t *d = &operator[](0);
int fl = 0;
for (int i = 0; i < l; i++) {
uint32_t c = d[i];
@@ -1535,13 +1817,15 @@ CharString String::utf8() const {
fl += 2;
} else if (c <= 0xffff) { // 16 bits
fl += 3;
- } else if (c <= 0x001fffff) { // 21 bits
+ } else if (c <= 0x0010ffff) { // 21 bits
fl += 4;
-
- } else if (c <= 0x03ffffff) { // 26 bits
- fl += 5;
- } else if (c <= 0x7fffffff) { // 31 bits
- fl += 6;
+ } else {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
+ return CharString();
+ }
+ if (c >= 0xd800 && c <= 0xdfff) {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
+ return CharString();
}
}
@@ -1561,35 +1845,17 @@ CharString String::utf8() const {
if (c <= 0x7f) { // 7 bits.
APPEND_CHAR(c);
} else if (c <= 0x7ff) { // 11 bits
-
APPEND_CHAR(uint32_t(0xc0 | ((c >> 6) & 0x1f))); // Top 5 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
} else if (c <= 0xffff) { // 16 bits
-
APPEND_CHAR(uint32_t(0xe0 | ((c >> 12) & 0x0f))); // Top 4 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
- } else if (c <= 0x001fffff) { // 21 bits
-
+ } else { // 21 bits
APPEND_CHAR(uint32_t(0xf0 | ((c >> 18) & 0x07))); // Top 3 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
- } else if (c <= 0x03ffffff) { // 26 bits
-
- APPEND_CHAR(uint32_t(0xf8 | ((c >> 24) & 0x03))); // Top 2 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Upper middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
- } else if (c <= 0x7fffffff) { // 31 bits
-
- APPEND_CHAR(uint32_t(0xfc | ((c >> 30) & 0x01))); // Top 1 bit.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 24) & 0x3f))); // Upper upper middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 18) & 0x3f))); // Lower upper middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 12) & 0x3f))); // Upper lower middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower lower middle 6 bits.
- APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
}
}
#undef APPEND_CHAR
@@ -1598,21 +1864,191 @@ CharString String::utf8() const {
return utf8s;
}
-/*
-String::String(CharType p_char) {
+String String::utf16(const char16_t *p_utf16, int p_len) {
+ String ret;
+ ret.parse_utf16(p_utf16, p_len);
+
+ return ret;
+}
+
+bool String::parse_utf16(const char16_t *p_utf16, int p_len) {
+#define _UNICERROR(m_err) print_error("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-16?");
+
+ if (!p_utf16) {
+ return true;
+ }
+
+ String aux;
+
+ int cstr_size = 0;
+ int str_size = 0;
+
+ /* HANDLE BOM (Byte Order Mark) */
+ bool byteswap = false; // assume correct endianness if no BOM found
+ if (p_len < 0 || p_len >= 1) {
+ bool has_bom = false;
+ if (uint16_t(p_utf16[0]) == 0xfeff) { // correct BOM, read as is
+ has_bom = true;
+ byteswap = false;
+ } else if (uint16_t(p_utf16[0]) == 0xfffe) { // backwards BOM, swap bytes
+ has_bom = true;
+ byteswap = true;
+ }
+ if (has_bom) {
+ if (p_len >= 0) {
+ p_len -= 1;
+ }
+ p_utf16 += 1;
+ }
+ }
+
+ {
+ const char16_t *ptrtmp = p_utf16;
+ const char16_t *ptrtmp_limit = &p_utf16[p_len];
+ int skip = 0;
+ while (ptrtmp != ptrtmp_limit && *ptrtmp) {
+ uint32_t c = (byteswap) ? BSWAP16(*ptrtmp) : *ptrtmp;
+ if (skip == 0) {
+ if ((c & 0xfffffc00) == 0xd800) {
+ skip = 1; // lead surrogate
+ } else if ((c & 0xfffffc00) == 0xdc00) {
+ _UNICERROR("invalid utf16 surrogate at " + num_int64(cstr_size));
+ return true; // invalid UTF16
+ } else {
+ skip = 0;
+ }
+ str_size++;
+ } else {
+ if ((c & 0xfffffc00) == 0xdc00) { // trail surrogate
+ --skip;
+ } else {
+ _UNICERROR("invalid utf16 surrogate at " + num_int64(cstr_size));
+ return true; // invalid UTF16
+ }
+ }
+
+ cstr_size++;
+ ptrtmp++;
+ }
+
+ if (skip) {
+ _UNICERROR("no space left");
+ return true; // not enough space
+ }
+ }
+
+ if (str_size == 0) {
+ clear();
+ return false;
+ }
+
+ resize(str_size + 1);
+ char32_t *dst = ptrw();
+ dst[str_size] = 0;
+
+ while (cstr_size) {
+ int len = 0;
+ uint32_t c = (byteswap) ? BSWAP16(*p_utf16) : *p_utf16;
+
+ if ((c & 0xfffffc00) == 0xd800) {
+ len = 2;
+ } else {
+ len = 1;
+ }
+
+ if (len > cstr_size) {
+ _UNICERROR("no space left");
+ return true; //not enough space
+ }
+
+ uint32_t unichar = 0;
+ if (len == 1) {
+ unichar = c;
+ } else {
+ uint32_t c2 = (byteswap) ? BSWAP16(p_utf16[1]) : p_utf16[1];
+ unichar = (c << 10UL) + c2 - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ }
+
+ *(dst++) = unichar;
+ cstr_size -= len;
+ p_utf16 += len;
+ }
- shared=nullptr;
- copy_from(p_char);
+ return false;
+#undef _UNICERROR
}
+Char16String String::utf16() const {
+ int l = length();
+ if (!l) {
+ return Char16String();
+ }
-*/
+ const char32_t *d = &operator[](0);
+ int fl = 0;
+ for (int i = 0; i < l; i++) {
+ uint32_t c = d[i];
+ if (c <= 0xffff) { // 16 bits.
+ fl += 1;
+ } else if (c <= 0x10ffff) { // 32 bits.
+ fl += 2;
+ } else {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
+ return Char16String();
+ }
+ if (c >= 0xd800 && c <= 0xdfff) {
+ print_error("Unicode parsing error: Invalid unicode codepoint " + num_int64(c, 16) + ".");
+ return Char16String();
+ }
+ }
+
+ Char16String utf16s;
+ if (fl == 0) {
+ return utf16s;
+ }
+
+ utf16s.resize(fl + 1);
+ uint16_t *cdst = (uint16_t *)utf16s.get_data();
+
+#define APPEND_CHAR(m_c) *(cdst++) = m_c
+
+ for (int i = 0; i < l; i++) {
+ uint32_t c = d[i];
+
+ if (c <= 0xffff) { // 16 bits.
+ APPEND_CHAR(c);
+ } else { // 32 bits.
+ APPEND_CHAR(uint32_t((c >> 10) + 0xd7c0)); // lead surrogate.
+ APPEND_CHAR(uint32_t((c & 0x3ff) | 0xdc00)); // trail surrogate.
+ }
+ }
+#undef APPEND_CHAR
+ *cdst = 0; //trailing zero
+
+ return utf16s;
+}
String::String(const char *p_str) {
copy_from(p_str);
}
-String::String(const CharType *p_str, int p_clip_to_len) {
+String::String(const wchar_t *p_str) {
+ copy_from(p_str);
+}
+
+String::String(const char32_t *p_str) {
+ copy_from(p_str);
+}
+
+String::String(const char *p_str, int p_clip_to_len) {
+ copy_from(p_str, p_clip_to_len);
+}
+
+String::String(const wchar_t *p_str, int p_clip_to_len) {
+ copy_from(p_str, p_clip_to_len);
+}
+
+String::String(const char32_t *p_str, int p_clip_to_len) {
copy_from(p_str, p_clip_to_len);
}
@@ -1620,7 +2056,6 @@ String::String(const StrRange &p_range) {
if (!p_range.c_str) {
return;
}
-
copy_from(p_range.c_str, p_range.len);
}
@@ -1629,7 +2064,7 @@ int64_t String::hex_to_int(bool p_with_prefix) const {
return 0;
}
- const CharType *s = ptr();
+ const char32_t *s = ptr();
int64_t sign = s[0] == '-' ? -1 : 1;
@@ -1647,7 +2082,7 @@ int64_t String::hex_to_int(bool p_with_prefix) const {
int64_t hex = 0;
while (*s) {
- CharType c = LOWERCASE(*s);
+ char32_t c = LOWERCASE(*s);
int64_t n;
if (c >= '0' && c <= '9') {
n = c - '0';
@@ -1672,7 +2107,7 @@ int64_t String::bin_to_int(bool p_with_prefix) const {
return 0;
}
- const CharType *s = ptr();
+ const char32_t *s = ptr();
int64_t sign = s[0] == '-' ? -1 : 1;
@@ -1690,7 +2125,7 @@ int64_t String::bin_to_int(bool p_with_prefix) const {
int64_t binary = 0;
while (*s) {
- CharType c = LOWERCASE(*s);
+ char32_t c = LOWERCASE(*s);
int64_t n;
if (c == '0' || c == '1') {
n = c - '0';
@@ -1719,7 +2154,7 @@ int64_t String::to_int() const {
int64_t sign = 1;
for (int i = 0; i < to; i++) {
- CharType c = operator[](i);
+ char32_t c = operator[](i);
if (c >= '0' && c <= '9') {
bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
@@ -1765,6 +2200,37 @@ int64_t String::to_int(const char *p_str, int p_len) {
return integer * sign;
}
+int64_t String::to_int(const wchar_t *p_str, int p_len) {
+ int to = 0;
+ if (p_len >= 0) {
+ to = p_len;
+ } else {
+ while (p_str[to] != 0 && p_str[to] != '.') {
+ to++;
+ }
+ }
+
+ int64_t integer = 0;
+ int64_t sign = 1;
+
+ for (int i = 0; i < to; i++) {
+ wchar_t c = p_str[i];
+ if (c >= '0' && c <= '9') {
+ bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8')));
+ ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_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';
+
+ } else if (c == '-' && integer == 0) {
+ sign = -sign;
+ } else if (c != ' ') {
+ break;
+ }
+ }
+
+ return integer * sign;
+}
+
bool String::is_numeric() const {
if (length() == 0) {
return false;
@@ -1776,14 +2242,13 @@ bool String::is_numeric() const {
}
bool dot = false;
for (int i = s; i < length(); i++) {
- CharType c = operator[](i);
+ char32_t c = operator[](i);
if (c == '.') {
if (dot) {
return false;
}
dot = true;
- }
- if (c < '0' || c > '9') {
+ } else if (c < '0' || c > '9') {
return false;
}
}
@@ -1945,11 +2410,11 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
}
expSign = false;
}
- if (!IS_DIGIT(CharType(*p))) {
+ if (!IS_DIGIT(char32_t(*p))) {
p = pExp;
goto done;
}
- while (IS_DIGIT(CharType(*p))) {
+ while (IS_DIGIT(char32_t(*p))) {
exp = exp * 10 + (*p - '0');
p += 1;
}
@@ -2007,19 +2472,18 @@ done:
#define READING_DONE 4
double String::to_float(const char *p_str) {
-#ifndef NO_USE_STDLIB
- return built_in_strtod<char>(p_str);
-//return atof(p_str); DOES NOT WORK ON ANDROID(??)
-#else
return built_in_strtod<char>(p_str);
-#endif
}
-double String::to_float(const CharType *p_str, const CharType **r_end) {
- return built_in_strtod<CharType>(p_str, (CharType **)r_end);
+double String::to_float(const char32_t *p_str, const char32_t **r_end) {
+ return built_in_strtod<char32_t>(p_str, (char32_t **)r_end);
}
-int64_t String::to_int(const CharType *p_str, int p_len, bool p_clamp) {
+double String::to_float(const wchar_t *p_str, const wchar_t **r_end) {
+ return built_in_strtod<wchar_t>(p_str, (wchar_t **)r_end);
+}
+
+int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) {
if (p_len == 0 || !p_str[0]) {
return 0;
}
@@ -2029,11 +2493,11 @@ int64_t String::to_int(const CharType *p_str, int p_len, bool p_clamp) {
int64_t sign = 1;
int reading = READING_SIGN;
- const CharType *str = p_str;
- const CharType *limit = &p_str[p_len];
+ const char32_t *str = p_str;
+ const char32_t *limit = &p_str[p_len];
while (*str && reading != READING_DONE && str != limit) {
- CharType c = *(str++);
+ char32_t c = *(str++);
switch (reading) {
case READING_SIGN: {
if (c >= '0' && c <= '9') {
@@ -2087,26 +2551,7 @@ double String::to_float() const {
if (empty()) {
return 0;
}
-#ifndef NO_USE_STDLIB
- return built_in_strtod<CharType>(c_str());
-//return wcstod(c_str(),nullptr ); DOES NOT WORK ON ANDROID :(
-#else
- return built_in_strtod<CharType>(c_str());
-#endif
-}
-
-bool operator==(const char *p_chr, const String &p_str) {
- return p_str == p_chr;
-}
-
-String operator+(const char *p_chr, const String &p_str) {
- String tmp = p_chr;
- tmp += p_str;
- return tmp;
-}
-
-String operator+(CharType p_chr, const String &p_str) {
- return (String::chr(p_chr) + p_str);
+ return built_in_strtod<char32_t>(get_data());
}
uint32_t String::hash(const char *p_cstr) {
@@ -2129,7 +2574,27 @@ uint32_t String::hash(const char *p_cstr, int p_len) {
return hashv;
}
-uint32_t String::hash(const CharType *p_cstr, int p_len) {
+uint32_t String::hash(const wchar_t *p_cstr, int p_len) {
+ uint32_t hashv = 5381;
+ for (int i = 0; i < p_len; i++) {
+ hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
+ }
+
+ return hashv;
+}
+
+uint32_t String::hash(const wchar_t *p_cstr) {
+ uint32_t hashv = 5381;
+ uint32_t c;
+
+ while ((c = *p_cstr++)) {
+ hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
+ }
+
+ return hashv;
+}
+
+uint32_t String::hash(const char32_t *p_cstr, int p_len) {
uint32_t hashv = 5381;
for (int i = 0; i < p_len; i++) {
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
@@ -2138,7 +2603,7 @@ uint32_t String::hash(const CharType *p_cstr, int p_len) {
return hashv;
}
-uint32_t String::hash(const CharType *p_cstr) {
+uint32_t String::hash(const char32_t *p_cstr) {
uint32_t hashv = 5381;
uint32_t c;
@@ -2152,7 +2617,7 @@ uint32_t String::hash(const CharType *p_cstr) {
uint32_t String::hash() const {
/* simple djb2 hashing */
- const CharType *chr = c_str();
+ const char32_t *chr = get_data();
uint32_t hashv = 5381;
uint32_t c;
@@ -2166,7 +2631,7 @@ uint32_t String::hash() const {
uint64_t String::hash64() const {
/* simple djb2 hashing */
- const CharType *chr = c_str();
+ const char32_t *chr = get_data();
uint64_t hashv = 5381;
uint64_t c;
@@ -2278,7 +2743,7 @@ String String::substr(int p_from, int p_chars) const {
}
String s = String();
- s.copy_from_unchecked(&c_str()[p_from], p_chars);
+ s.copy_from_unchecked(&get_data()[p_from], p_chars);
return s;
}
@@ -2295,8 +2760,8 @@ int String::find(const String &p_str, int p_from) const {
return -1; // won't find anything!
}
- const CharType *src = c_str();
- const CharType *str = p_str.c_str();
+ const char32_t *src = get_data();
+ const char32_t *str = p_str.get_data();
for (int i = p_from; i <= (len - src_len); i++) {
bool found = true;
@@ -2333,7 +2798,7 @@ int String::find(const char *p_str, int p_from) const {
return -1; // won't find anything!
}
- const CharType *src = c_str();
+ const char32_t *src = get_data();
int src_len = 0;
while (p_str[src_len] != '\0') {
@@ -2341,7 +2806,7 @@ int String::find(const char *p_str, int p_from) const {
}
if (src_len == 1) {
- const char needle = p_str[0];
+ const char32_t needle = p_str[0];
for (int i = p_from; i < len; i++) {
if (src[i] == needle) {
@@ -2360,7 +2825,7 @@ int String::find(const char *p_str, int p_from) const {
return -1;
}
- if (src[read_pos] != p_str[j]) {
+ if (src[read_pos] != (char32_t)p_str[j]) {
found = false;
break;
}
@@ -2375,7 +2840,7 @@ int String::find(const char *p_str, int p_from) const {
return -1;
}
-int String::find_char(const CharType &p_char, int p_from) const {
+int String::find_char(const char32_t &p_char, int p_from) const {
return _cowdata.find(p_char, p_from);
}
@@ -2396,7 +2861,7 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
return -1; // won't find anything!
}
- const CharType *src = c_str();
+ const char32_t *src = get_data();
for (int i = p_from; i < len; i++) {
bool found = true;
@@ -2405,7 +2870,7 @@ int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
if (r_key) {
*r_key = k;
}
- const CharType *cmp = keys[k].c_str();
+ const char32_t *cmp = keys[k].get_data();
int l = keys[k].length();
for (int j = 0; j < l; j++) {
@@ -2445,7 +2910,7 @@ int String::findn(const String &p_str, int p_from) const {
return -1; // won't find anything!
}
- const CharType *srcd = c_str();
+ const char32_t *srcd = get_data();
for (int i = p_from; i <= (length() - src_len); i++) {
bool found = true;
@@ -2457,8 +2922,8 @@ int String::findn(const String &p_str, int p_from) const {
return -1;
}
- CharType src = _find_lower(srcd[read_pos]);
- CharType dst = _find_lower(p_str[j]);
+ char32_t src = _find_lower(srcd[read_pos]);
+ char32_t dst = _find_lower(p_str[j]);
if (src != dst) {
found = false;
@@ -2495,7 +2960,7 @@ int String::rfind(const String &p_str, int p_from) const {
return -1; // won't find anything!
}
- const CharType *src = c_str();
+ const char32_t *src = get_data();
for (int i = p_from; i >= 0; i--) {
bool found = true;
@@ -2542,7 +3007,7 @@ int String::rfindn(const String &p_str, int p_from) const {
return -1; // won't find anything!
}
- const CharType *src = c_str();
+ const char32_t *src = get_data();
for (int i = p_from; i >= 0; i--) {
bool found = true;
@@ -2554,8 +3019,8 @@ int String::rfindn(const String &p_str, int p_from) const {
return -1;
}
- CharType srcc = _find_lower(src[read_pos]);
- CharType dstc = _find_lower(p_str[j]);
+ char32_t srcc = _find_lower(src[read_pos]);
+ char32_t dstc = _find_lower(p_str[j]);
if (srcc != dstc) {
found = false;
@@ -2589,8 +3054,8 @@ bool String::begins_with(const String &p_string) const {
return true;
}
- const CharType *src = &p_string[0];
- const CharType *str = &operator[](0);
+ const char32_t *src = &p_string[0];
+ const char32_t *str = &operator[](0);
int i = 0;
for (; i < l; i++) {
@@ -2609,11 +3074,11 @@ bool String::begins_with(const char *p_string) const {
return false;
}
- const CharType *str = &operator[](0);
+ const char32_t *str = &operator[](0);
int i = 0;
while (*p_string && i < l) {
- if (*p_string != str[i]) {
+ if ((char32_t)*p_string != str[i]) {
return false;
}
i++;
@@ -2657,7 +3122,7 @@ int String::_count(const String &p_string, int p_from, int p_to, bool p_case_ins
}
if (p_from == 0 && p_to == len) {
str = String();
- str.copy_from_unchecked(&c_str()[0], len);
+ str.copy_from_unchecked(&get_data()[0], len);
} else {
str = substr(p_from, p_to - p_from);
}
@@ -2695,14 +3160,14 @@ bool String::_base_is_subsequence_of(const String &p_string, bool case_insensiti
return false;
}
- const CharType *src = &operator[](0);
- const CharType *tgt = &p_string[0];
+ const char32_t *src = &operator[](0);
+ const char32_t *tgt = &p_string[0];
for (; *src && *tgt; tgt++) {
bool match = false;
if (case_insensitive) {
- CharType srcc = _find_lower(*src);
- CharType tgtc = _find_lower(*tgt);
+ char32_t srcc = _find_lower(*src);
+ char32_t tgtc = _find_lower(*tgt);
match = srcc == tgtc;
} else {
match = *src == *tgt;
@@ -2748,8 +3213,8 @@ float String::similarity(const String &p_string) const {
int src_size = src_bigrams.size();
int tgt_size = tgt_bigrams.size();
- float sum = src_size + tgt_size;
- float inter = 0;
+ double sum = src_size + tgt_size;
+ double inter = 0;
for (int i = 0; i < src_size; i++) {
for (int j = 0; j < tgt_size; j++) {
if (src_bigrams[i] == tgt_bigrams[j]) {
@@ -2762,7 +3227,7 @@ float String::similarity(const String &p_string) const {
return (2.0f * inter) / sum;
}
-static bool _wildcard_match(const CharType *p_pattern, const CharType *p_string, bool p_case_sensitive) {
+static bool _wildcard_match(const char32_t *p_pattern, const char32_t *p_string, bool p_case_sensitive) {
switch (*p_pattern) {
case '\0':
return !*p_string;
@@ -2781,14 +3246,14 @@ bool String::match(const String &p_wildcard) const {
return false;
}
- return _wildcard_match(p_wildcard.c_str(), c_str(), true);
+ return _wildcard_match(p_wildcard.get_data(), get_data(), true);
}
bool String::matchn(const String &p_wildcard) const {
if (!p_wildcard.length() || !length()) {
return false;
}
- return _wildcard_match(p_wildcard.c_str(), c_str(), false);
+ return _wildcard_match(p_wildcard.get_data(), get_data(), false);
}
String String::format(const Variant &values, String placeholder) const {
@@ -2938,9 +3403,10 @@ String String::repeat(int p_count) const {
ERR_FAIL_COND_V_MSG(p_count < 0, "", "Parameter count should be a positive number.");
String new_string;
- const CharType *src = this->c_str();
+ const char32_t *src = this->get_data();
new_string.resize(length() * p_count + 1);
+ new_string[length() * p_count] = 0;
for (int i = 0; i < p_count; i++) {
for (int j = 0; j < length(); j++) {
@@ -2975,7 +3441,7 @@ String String::right(int p_pos) const {
return substr(p_pos, (length() - p_pos));
}
-CharType String::ord_at(int p_idx) const {
+char32_t String::ord_at(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, length(), 0);
return operator[](p_idx);
}
@@ -2989,7 +3455,7 @@ String String::dedent() const {
int indent_stop = -1;
for (int i = 0; i < length(); i++) {
- CharType c = operator[](i);
+ char32_t c = operator[](i);
if (c == '\n') {
if (has_text) {
new_string += substr(indent_stop, i - indent_stop);
@@ -3218,7 +3684,7 @@ bool String::is_valid_identifier() const {
return false;
}
- const wchar_t *str = &operator[](0);
+ const char32_t *str = &operator[](0);
for (int i = 0; i < len; i++) {
if (i == 0) {
@@ -3237,36 +3703,14 @@ bool String::is_valid_identifier() const {
return true;
}
-//kind of poor should be rewritten properly
-
-String String::word_wrap(int p_chars_per_line) const {
- int from = 0;
- int last_space = 0;
- String ret;
- for (int i = 0; i < length(); i++) {
- if (i - from >= p_chars_per_line) {
- if (last_space == -1) {
- ret += substr(from, i - from + 1) + "\n";
- } else {
- ret += substr(from, last_space - from) + "\n";
- i = last_space; //rewind
- }
- from = i + 1;
- last_space = -1;
- } else if (operator[](i) == ' ' || operator[](i) == '\t') {
- last_space = i;
- } else if (operator[](i) == '\n') {
- ret += substr(from, i - from) + "\n";
- from = i + 1;
- last_space = -1;
- }
- }
-
- if (from < length()) {
- ret += substr(from, length());
+bool String::is_valid_string() const {
+ int l = length();
+ const char32_t *src = get_data();
+ bool valid = true;
+ for (int i = 0; i < l; i++) {
+ valid = valid && (src[i] < 0xd800 || (src[i] > 0xdfff && src[i] <= 0x10ffff));
}
-
- return ret;
+ return valid;
}
String String::http_escape() const {
@@ -3297,9 +3741,9 @@ String String::http_unescape() const {
String res;
for (int i = 0; i < length(); ++i) {
if (ord_at(i) == '%' && i + 2 < length()) {
- CharType ord1 = ord_at(i + 1);
+ char32_t ord1 = ord_at(i + 1);
if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) {
- CharType ord2 = ord_at(i + 2);
+ char32_t ord2 = ord_at(i + 2);
if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) {
char bytes[3] = { (char)ord1, (char)ord2, 0 };
res += (char)strtol(bytes, nullptr, 16);
@@ -3389,18 +3833,18 @@ for (int i=1;i<32;i++) {
return str;
}
-static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, CharType *p_dst) {
+static _FORCE_INLINE_ int _xml_unescape(const char32_t *p_src, int p_src_len, char32_t *p_dst) {
int len = 0;
while (p_src_len) {
if (*p_src == '&') {
int eat = 0;
if (p_src_len >= 4 && p_src[1] == '#') {
- CharType c = 0;
+ char32_t c = 0;
for (int i = 2; i < p_src_len; i++) {
eat = i + 1;
- CharType ct = p_src[i];
+ char32_t ct = p_src[i];
if (ct == ';') {
break;
} else if (ct >= '0' && ct <= '9') {
@@ -3476,12 +3920,12 @@ static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, Ch
String String::xml_unescape() const {
String str;
int l = length();
- int len = _xml_unescape(c_str(), l, nullptr);
+ int len = _xml_unescape(get_data(), l, nullptr);
if (len == 0) {
return String();
}
str.resize(len + 1);
- _xml_unescape(c_str(), l, str.ptrw());
+ _xml_unescape(get_data(), l, str.ptrw());
str[len] = 0;
return str;
}
@@ -3602,7 +4046,7 @@ bool String::is_valid_hex_number(bool p_with_prefix) const {
}
for (int i = from; i < len; i++) {
- CharType c = operator[](i);
+ char32_t c = operator[](i);
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
continue;
}
@@ -3917,7 +4361,7 @@ String String::percent_decode() const {
String String::property_name_encode() const {
// Escape and quote strings with extended ASCII or further Unicode characters
// as well as '"', '=' or ' ' (32)
- const CharType *cstr = c_str();
+ const char32_t *cstr = get_data();
for (int i = 0; cstr[i]; i++) {
if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) {
return "\"" + c_escape_multiline() + "\"";
@@ -3984,7 +4428,7 @@ String String::lpad(int min_length, const String &character) const {
// In case of an error, the string returned is the error description and "error" is true.
String String::sprintf(const Array &values, bool *error) const {
String formatted;
- CharType *self = (CharType *)c_str();
+ char32_t *self = (char32_t *)get_data();
bool in_format = false;
int value_index = 0;
int min_chars = 0;
@@ -3997,7 +4441,7 @@ String String::sprintf(const Array &values, bool *error) const {
*error = true;
for (; *self; self++) {
- const CharType c = *self;
+ const char32_t c = *self;
if (in_format) { // We have % - lets see what else we get.
switch (c) {
@@ -4134,9 +4578,11 @@ String String::sprintf(const Array &values, bool *error) const {
if (values[value_index].is_num()) {
int value = values[value_index];
if (value < 0) {
- return "unsigned byte integer is lower than maximum";
- } else if (value > 255) {
- return "unsigned byte integer is greater than maximum";
+ return "unsigned integer is lower than minimum";
+ } else if (value >= 0xd800 && value <= 0xdfff) {
+ return "unsigned integer is invalid Unicode character";
+ } else if (value > 0x10ffff) {
+ return "unsigned integer is greater than maximum";
}
str = chr(values[value_index]);
} else if (values[value_index].get_type() == Variant::STRING) {
diff --git a/core/ustring.h b/core/ustring.h
index 7a1c1a5232..1f8a5d7e7d 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -36,8 +36,13 @@
#include "core/typedefs.h"
#include "core/vector.h"
+/*************************************************************************/
+/* CharProxy */
+/*************************************************************************/
+
template <class T>
class CharProxy {
+ friend class Char16String;
friend class CharString;
friend class String;
@@ -71,6 +76,54 @@ public:
}
};
+/*************************************************************************/
+/* Char16String */
+/*************************************************************************/
+
+class Char16String {
+ CowData<char16_t> _cowdata;
+ static const char16_t _null;
+
+public:
+ _FORCE_INLINE_ char16_t *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const char16_t *ptr() const { return _cowdata.ptr(); }
+ _FORCE_INLINE_ int size() const { return _cowdata.size(); }
+ Error resize(int p_size) { return _cowdata.resize(p_size); }
+
+ _FORCE_INLINE_ char16_t get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const char16_t &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ const char16_t &operator[](int p_index) const {
+ if (unlikely(p_index == _cowdata.size())) {
+ return _null;
+ }
+
+ return _cowdata.get(p_index);
+ }
+ _FORCE_INLINE_ CharProxy<char16_t> operator[](int p_index) { return CharProxy<char16_t>(p_index, _cowdata); }
+
+ _FORCE_INLINE_ Char16String() {}
+ _FORCE_INLINE_ Char16String(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
+ _FORCE_INLINE_ Char16String &operator=(const Char16String &p_str) {
+ _cowdata._ref(p_str._cowdata);
+ return *this;
+ }
+ _FORCE_INLINE_ Char16String(const char16_t *p_cstr) { copy_from(p_cstr); }
+
+ Char16String &operator=(const char16_t *p_cstr);
+ bool operator<(const Char16String &p_right) const;
+ Char16String &operator+=(char16_t p_char);
+ int length() const { return size() ? size() - 1 : 0; }
+ const char16_t *get_data() const;
+ operator const char16_t *() const { return get_data(); };
+
+protected:
+ void copy_from(const char16_t *p_cstr);
+};
+
+/*************************************************************************/
+/* CharString */
+/*************************************************************************/
+
class CharString {
CowData<char> _cowdata;
static const char _null;
@@ -94,7 +147,7 @@ public:
_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ CharString operator=(const CharString &p_str) {
+ _FORCE_INLINE_ CharString &operator=(const CharString &p_str) {
_cowdata._ref(p_str._cowdata);
return *this;
}
@@ -111,26 +164,35 @@ protected:
void copy_from(const char *p_cstr);
};
-typedef wchar_t CharType;
+/*************************************************************************/
+/* String */
+/*************************************************************************/
struct StrRange {
- const CharType *c_str;
+ const char32_t *c_str;
int len;
- StrRange(const CharType *p_c_str = nullptr, int p_len = 0) {
+ StrRange(const char32_t *p_c_str = nullptr, int p_len = 0) {
c_str = p_c_str;
len = p_len;
}
};
class String {
- CowData<CharType> _cowdata;
- static const CharType _null;
+ CowData<char32_t> _cowdata;
+ static const char32_t _null;
void copy_from(const char *p_cstr);
- void copy_from(const CharType *p_cstr, const int p_clip_to = -1);
- void copy_from(const CharType &p_char);
- void copy_from_unchecked(const CharType *p_char, const int p_length);
+ void copy_from(const char *p_cstr, const int p_clip_to);
+ void copy_from(const wchar_t *p_cstr);
+ void copy_from(const wchar_t *p_cstr, const int p_clip_to);
+ void copy_from(const char32_t *p_cstr);
+ void copy_from(const char32_t *p_cstr, const int p_clip_to);
+
+ void copy_from(const char32_t &p_char);
+
+ void copy_from_unchecked(const char32_t *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;
@@ -140,48 +202,56 @@ public:
npos = -1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
};
- _FORCE_INLINE_ CharType *ptrw() { return _cowdata.ptrw(); }
- _FORCE_INLINE_ const CharType *ptr() const { return _cowdata.ptr(); }
+ _FORCE_INLINE_ char32_t *ptrw() { return _cowdata.ptrw(); }
+ _FORCE_INLINE_ const char32_t *ptr() const { return _cowdata.ptr(); }
void remove(int p_index) { _cowdata.remove(p_index); }
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ CharType get(int p_index) const { return _cowdata.get(p_index); }
- _FORCE_INLINE_ void set(int p_index, const CharType &p_elem) { _cowdata.set(p_index, p_elem); }
+ _FORCE_INLINE_ char32_t get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ void set(int p_index, const char32_t &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
- _FORCE_INLINE_ const CharType &operator[](int p_index) const {
+ _FORCE_INLINE_ const char32_t &operator[](int p_index) const {
if (unlikely(p_index == _cowdata.size())) {
return _null;
}
return _cowdata.get(p_index);
}
- _FORCE_INLINE_ CharProxy<CharType> operator[](int p_index) { return CharProxy<CharType>(p_index, _cowdata); }
+ _FORCE_INLINE_ CharProxy<char32_t> operator[](int p_index) { return CharProxy<char32_t>(p_index, _cowdata); }
bool operator==(const String &p_str) const;
bool operator!=(const String &p_str) const;
String operator+(const String &p_str) const;
- //String operator+(CharType p_char) const;
String &operator+=(const String &);
- String &operator+=(CharType p_char);
+ String &operator+=(char32_t p_char);
String &operator+=(const char *p_str);
- String &operator+=(const CharType *p_str);
+ String &operator+=(const wchar_t *p_str);
+ String &operator+=(const char32_t *p_str);
/* Compatibility Operators */
void operator=(const char *p_str);
- void operator=(const CharType *p_str);
+ void operator=(const wchar_t *p_str);
+ void operator=(const char32_t *p_str);
+
bool operator==(const char *p_str) const;
- bool operator==(const CharType *p_str) const;
+ bool operator==(const wchar_t *p_str) const;
+ bool operator==(const char32_t *p_str) const;
bool operator==(const StrRange &p_str_range) const;
+
bool operator!=(const char *p_str) const;
- bool operator!=(const CharType *p_str) const;
- bool operator<(const CharType *p_str) const;
+ bool operator!=(const wchar_t *p_str) const;
+ bool operator!=(const char32_t *p_str) const;
+
+ bool operator<(const char32_t *p_str) const;
bool operator<(const char *p_str) const;
+ bool operator<(const wchar_t *p_str) const;
+
bool operator<(const String &p_str) const;
bool operator<=(const String &p_str) const;
@@ -189,7 +259,7 @@ public:
signed char nocasecmp_to(const String &p_str) const;
signed char naturalnocasecmp_to(const String &p_str) const;
- const CharType *c_str() const;
+ const char32_t *get_data() const;
/* standard size stuff */
_FORCE_INLINE_ int length() const {
@@ -197,11 +267,13 @@ public:
return s ? (s - 1) : 0; // length does not include zero
}
+ bool is_valid_string() const;
+
/* complex helpers */
String substr(int p_from, int p_chars = -1) const;
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed
- int find_char(const CharType &p_char, int p_from = 0) const; ///< return <0 if failed
+ int find_char(const char32_t &p_char, int p_from = 0) const; ///< return <0 if failed
int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive
int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed
int rfindn(const String &p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive
@@ -238,26 +310,31 @@ public:
static String num_real(double p_num);
static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false);
static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false);
- static String chr(CharType p_char);
+ static String chr(char32_t p_char);
static String md5(const uint8_t *p_md5);
static String hex_encode_buffer(const uint8_t *p_buffer, int p_len);
bool is_numeric() const;
- double to_float() const;
+ double to_float() const;
int64_t hex_to_int(bool p_with_prefix = true) const;
int64_t bin_to_int(bool p_with_prefix = true) const;
int64_t to_int() const;
+
static int64_t to_int(const char *p_str, int p_len = -1);
+ static int64_t to_int(const wchar_t *p_str, int p_len = -1);
+ static int64_t to_int(const char32_t *p_str, int p_len = -1, bool p_clamp = false);
+
static double to_float(const char *p_str);
- static double to_float(const CharType *p_str, const CharType **r_end = nullptr);
- static int64_t to_int(const CharType *p_str, int p_len = -1, bool p_clamp = false);
+ static double to_float(const wchar_t *p_str, const wchar_t **r_end = nullptr);
+ static double to_float(const char32_t *p_str, const char32_t **r_end = nullptr);
+
String capitalize() const;
String camelcase_to_underscore(bool lowercase = true) const;
String get_with_code_lines() const;
int get_slice_count(String p_splitter) const;
String get_slice(String p_splitter, int p_slice) const;
- String get_slicec(CharType p_splitter, int p_slice) const;
+ String get_slicec(char32_t p_splitter, int p_slice) const;
Vector<String> split(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
Vector<String> rsplit(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
@@ -267,10 +344,10 @@ public:
Vector<int> split_ints(const String &p_splitter, bool p_allow_empty = true) const;
Vector<int> split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const;
- String join(Vector<String> parts);
+ String join(Vector<String> parts) const;
- static CharType char_uppercase(CharType p_char);
- static CharType char_lowercase(CharType p_char);
+ static char32_t char_uppercase(char32_t p_char);
+ static char32_t char_lowercase(char32_t p_char);
String to_upper() const;
String to_lower() const;
@@ -287,7 +364,7 @@ public:
String get_extension() const;
String get_basename() const;
String plus_file(const String &p_file) const;
- CharType ord_at(int p_idx) const;
+ char32_t ord_at(int p_idx) const;
void erase(int p_pos, int p_chars);
@@ -296,8 +373,14 @@ public:
bool parse_utf8(const char *p_utf8, int p_len = -1); //return true on error
static String utf8(const char *p_utf8, int p_len = -1);
- static uint32_t hash(const CharType *p_cstr, int p_len); /* hash the string */
- static uint32_t hash(const CharType *p_cstr); /* hash the string */
+ Char16String utf16() const;
+ bool parse_utf16(const char16_t *p_utf16, int p_len = -1); //return true on error
+ static String utf16(const char16_t *p_utf16, int p_len = -1);
+
+ static uint32_t hash(const char32_t *p_cstr, int p_len); /* hash the string */
+ static uint32_t hash(const char32_t *p_cstr); /* hash the string */
+ static uint32_t hash(const wchar_t *p_cstr, int p_len); /* hash the string */
+ static uint32_t hash(const wchar_t *p_cstr); /* hash the string */
static uint32_t hash(const char *p_cstr, int p_len); /* hash the string */
static uint32_t hash(const char *p_cstr); /* hash the string */
uint32_t hash() const; /* hash the string */
@@ -348,24 +431,30 @@ public:
/**
* The constructors must not depend on other overloads
*/
- /* String(CharType p_char);*/
+ /* String(char32_t p_char);*/
_FORCE_INLINE_ String() {}
_FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
- String operator=(const String &p_str) {
+ String &operator=(const String &p_str) {
_cowdata._ref(p_str._cowdata);
return *this;
}
String(const char *p_str);
- String(const CharType *p_str, int p_clip_to_len = -1);
+ String(const wchar_t *p_str);
+ String(const char32_t *p_str);
+ String(const char *p_str, int p_clip_to_len);
+ String(const wchar_t *p_str, int p_clip_to_len);
+ String(const char32_t *p_str, int p_clip_to_len);
String(const StrRange &p_range);
};
bool operator==(const char *p_chr, const String &p_str);
+bool operator==(const wchar_t *p_chr, const String &p_str);
String operator+(const char *p_chr, const String &p_str);
-String operator+(CharType p_chr, const String &p_str);
+String operator+(const wchar_t *p_chr, const String &p_str);
+String operator+(char32_t p_chr, const String &p_str);
String itos(int64_t p_val);
String uitos(uint64_t p_val);
@@ -387,15 +476,18 @@ struct NaturalNoCaseComparator {
template <typename L, typename R>
_FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) {
while (true) {
- if (*l_ptr == 0 && *r_ptr == 0) {
+ const char32_t l = *l_ptr;
+ const char32_t r = *r_ptr;
+
+ if (l == 0 && r == 0) {
return false;
- } else if (*l_ptr == 0) {
+ } else if (l == 0) {
return true;
- } else if (*r_ptr == 0) {
+ } else if (r == 0) {
return false;
- } else if (*l_ptr < *r_ptr) {
+ } else if (l < r) {
return true;
- } else if (*l_ptr > *r_ptr) {
+ } else if (l > r) {
return false;
}
@@ -432,7 +524,7 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String RTR(const String &p_text, const String &p_context = "");
String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
-bool is_symbol(CharType c);
+bool is_symbol(char32_t c);
bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
#endif // USTRING_H
diff --git a/core/variant.cpp b/core/variant.cpp
index c19ce79e64..181ced0f32 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1558,7 +1558,7 @@ Variant::operator unsigned char() const {
}
}
-Variant::operator CharType() const {
+Variant::operator char32_t() const {
return operator unsigned int();
}
@@ -2445,7 +2445,7 @@ Variant::Variant(const char *const p_cstring) {
memnew_placement(_data._mem, String((const char *)p_cstring));
}
-Variant::Variant(const CharType *p_wstring) {
+Variant::Variant(const char32_t *p_wstring) {
type = STRING;
memnew_placement(_data._mem, String(p_wstring));
}
diff --git a/core/variant.h b/core/variant.h
index 50b7a21eda..112003a7ae 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -120,6 +120,7 @@ public:
private:
friend struct _VariantCall;
+ friend class VariantInternal;
// Variant takes 20 bytes when real_t is float, and 36 if double
// it only allocates extra memory for aabb/matrix.
@@ -245,7 +246,7 @@ public:
operator ObjectID() const;
- operator CharType() const;
+ operator char32_t() const;
operator float() const;
operator double() const;
operator String() const;
@@ -322,7 +323,7 @@ public:
Variant(const String &p_string);
Variant(const StringName &p_string);
Variant(const char *const p_cstring);
- Variant(const CharType *p_wstring);
+ Variant(const char32_t *p_wstring);
Variant(const Vector2 &p_vector2);
Variant(const Vector2i &p_vector2i);
Variant(const Rect2 &p_rect2);
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 91af127d32..5fd970c8e1 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -239,6 +239,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(String, casecmp_to);
VCALL_LOCALMEM1R(String, nocasecmp_to);
+ VCALL_LOCALMEM1R(String, naturalnocasecmp_to);
VCALL_LOCALMEM0R(String, length);
VCALL_LOCALMEM3R(String, count);
VCALL_LOCALMEM3R(String, countn);
@@ -311,6 +312,8 @@ struct _VariantCall {
VCALL_LOCALMEM0R(String, to_int);
VCALL_LOCALMEM0R(String, to_float);
VCALL_LOCALMEM0R(String, hex_to_int);
+ VCALL_LOCALMEM2R(String, lpad);
+ VCALL_LOCALMEM2R(String, rpad);
VCALL_LOCALMEM1R(String, pad_decimals);
VCALL_LOCALMEM1R(String, pad_zeros);
VCALL_LOCALMEM1R(String, trim_prefix);
@@ -350,6 +353,39 @@ struct _VariantCall {
r_ret = retval;
}
+ static void _call_String_to_utf16(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ String *s = reinterpret_cast<String *>(p_self._data._mem);
+ if (s->empty()) {
+ r_ret = PackedByteArray();
+ return;
+ }
+ Char16String charstr = s->utf16();
+
+ PackedByteArray retval;
+ size_t len = charstr.length() * 2;
+ retval.resize(len);
+ uint8_t *w = retval.ptrw();
+ copymem(w, (const void *)charstr.ptr(), len);
+
+ r_ret = retval;
+ }
+
+ static void _call_String_to_utf32(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ String *s = reinterpret_cast<String *>(p_self._data._mem);
+ if (s->empty()) {
+ r_ret = PackedByteArray();
+ return;
+ }
+
+ PackedByteArray retval;
+ size_t len = s->length() * 4;
+ retval.resize(len);
+ uint8_t *w = retval.ptrw();
+ copymem(w, (const void *)s->ptr(), len);
+
+ r_ret = retval;
+ }
+
VCALL_LOCALMEM1R(Vector2, distance_to);
VCALL_LOCALMEM1R(Vector2, distance_squared_to);
VCALL_LOCALMEM0R(Vector2, length);
@@ -594,14 +630,14 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Array, min);
static void _call_PackedByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
String s;
- if (ba->size() > 0) {
- const uint8_t *r = ba->ptr();
+ if (ba->array.size() > 0) {
+ const uint8_t *r = ba->array.ptr();
CharString cs;
- cs.resize(ba->size() + 1);
- copymem(cs.ptrw(), r, ba->size());
- cs[ba->size()] = 0;
+ cs.resize(ba->array.size() + 1);
+ copymem(cs.ptrw(), r, ba->array.size());
+ cs[ba->array.size()] = 0;
s = cs.get_data();
}
@@ -609,32 +645,54 @@ struct _VariantCall {
}
static void _call_PackedByteArray_get_string_from_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
+
+ String s;
+ if (ba->array.size() > 0) {
+ const uint8_t *r = ba->array.ptr();
+ s.parse_utf8((const char *)r, ba->array.size());
+ }
+ r_ret = s;
+ }
+
+ static void _call_PackedByteArray_get_string_from_utf16(Variant &r_ret, Variant &p_self, const Variant **p_args) {
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
String s;
if (ba->size() > 0) {
const uint8_t *r = ba->ptr();
- s.parse_utf8((const char *)r, ba->size());
+ s.parse_utf16((const char16_t *)r, ba->size() / 2);
}
r_ret = s;
}
- static void _call_PackedByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PackedByteArray_get_string_from_utf32(Variant &r_ret, Variant &p_self, const Variant **p_args) {
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
- PackedByteArray compressed;
+ String s;
if (ba->size() > 0) {
- Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]);
+ const uint8_t *r = ba->ptr();
+ s = String((const char32_t *)r, ba->size() / 4);
+ }
+ r_ret = s;
+ }
+
+ static void _call_PackedByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
+ PackedByteArray compressed;
- compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode));
- int result = Compression::compress(compressed.ptrw(), ba->ptr(), ba->size(), mode);
+ if (ba->array.size() > 0) {
+ Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]);
+ compressed.resize(Compression::get_max_compressed_buffer_size(ba->array.size(), mode));
+ int result = Compression::compress(compressed.ptrw(), ba->array.ptr(), ba->array.size(), mode);
result = result >= 0 ? result : 0;
compressed.resize(result);
}
+
r_ret = compressed;
}
static void _call_PackedByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
PackedByteArray decompressed;
Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);
@@ -646,7 +704,7 @@ struct _VariantCall {
}
decompressed.resize(buffer_size);
- int result = Compression::decompress(decompressed.ptrw(), buffer_size, ba->ptr(), ba->size(), mode);
+ int result = Compression::decompress(decompressed.ptrw(), buffer_size, ba->array.ptr(), ba->array.size(), mode);
result = result >= 0 ? result : 0;
decompressed.resize(result);
@@ -654,14 +712,31 @@ struct _VariantCall {
r_ret = decompressed;
}
+ static void _call_PackedByteArray_decompress_dynamic(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
+ PackedByteArray decompressed;
+ int max_output_size = (int)(*p_args[0]);
+ Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);
+
+ int result = Compression::decompress_dynamic(&decompressed, max_output_size, ba->array.ptr(), ba->array.size(), mode);
+
+ if (result == OK) {
+ r_ret = decompressed;
+ } else {
+ decompressed.clear();
+ r_ret = decompressed;
+ ERR_FAIL_MSG("Decompression failed.");
+ }
+ }
+
static void _call_PackedByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
- if (ba->size() == 0) {
+ Variant::PackedArrayRef<uint8_t> *ba = reinterpret_cast<Variant::PackedArrayRef<uint8_t> *>(p_self._data.packed_array);
+ if (ba->array.size() == 0) {
r_ret = String();
return;
}
- const uint8_t *r = ba->ptr();
- String s = String::hex_encode_buffer(&r[0], ba->size());
+ const uint8_t *r = ba->array.ptr();
+ String s = String::hex_encode_buffer(&r[0], ba->array.size());
r_ret = s;
}
@@ -960,7 +1035,7 @@ struct _VariantCall {
VCALL_PTR0R(Basis, get_orthogonal_index);
VCALL_PTR0R(Basis, orthonormalized);
VCALL_PTR2R(Basis, slerp);
- VCALL_PTR2R(Basis, is_equal_approx); // TODO: Break compatibility in 4.0 to change this to an instance method (a.is_equal_approx(b) as VCALL_PTR1R) for consistency.
+ VCALL_PTR1R(Basis, is_equal_approx);
VCALL_PTR0R(Basis, get_rotation_quat);
VCALL_PTR0R(Transform, inverse);
@@ -1789,6 +1864,7 @@ void register_variant_methods() {
/* STRING */
ADDFUNC1R(STRING, INT, String, casecmp_to, STRING, "to", varray());
ADDFUNC1R(STRING, INT, String, nocasecmp_to, STRING, "to", varray());
+ ADDFUNC1R(STRING, INT, String, naturalnocasecmp_to, STRING, "to", varray());
ADDFUNC0R(STRING, INT, String, length, varray());
ADDFUNC2R(STRING, STRING, String, substr, INT, "from", INT, "len", varray(-1));
@@ -1867,6 +1943,8 @@ void register_variant_methods() {
ADDFUNC0R(STRING, INT, String, to_int, varray());
ADDFUNC0R(STRING, FLOAT, String, to_float, varray());
ADDFUNC0R(STRING, INT, String, hex_to_int, varray());
+ ADDFUNC2R(STRING, STRING, String, lpad, INT, "min_length", STRING, "character", varray(" "));
+ ADDFUNC2R(STRING, STRING, String, rpad, INT, "min_length", STRING, "character", varray(" "));
ADDFUNC1R(STRING, STRING, String, pad_decimals, INT, "digits", varray());
ADDFUNC1R(STRING, STRING, String, pad_zeros, INT, "digits", varray());
ADDFUNC1R(STRING, STRING, String, trim_prefix, STRING, "prefix", varray());
@@ -1874,6 +1952,8 @@ void register_variant_methods() {
ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_ascii, varray());
ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_utf8, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_utf16, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_utf32, varray());
ADDFUNC0R(VECTOR2, FLOAT, Vector2, angle, varray());
ADDFUNC1R(VECTOR2, FLOAT, Vector2, angle_to, VECTOR2, "to", varray());
@@ -2109,9 +2189,12 @@ void register_variant_methods() {
ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_ascii, varray());
ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_utf8, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_utf16, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_utf32, varray());
ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, hex_encode, varray());
ADDFUNC1R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, compress, INT, "compression_mode", varray(0));
ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
+ ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, decompress_dynamic, INT, "max_output_size", INT, "compression_mode", varray(0));
ADDFUNC0R(PACKED_INT32_ARRAY, INT, PackedInt32Array, size, varray());
ADDFUNC0R(PACKED_INT32_ARRAY, BOOL, PackedInt32Array, empty, varray());
@@ -2273,7 +2356,7 @@ void register_variant_methods() {
ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray());
ADDFUNC0R(BASIS, INT, Basis, get_orthogonal_index, varray());
ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", FLOAT, "t", varray());
- ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", FLOAT, "epsilon", varray(CMP_EPSILON)); // TODO: Replace in 4.0, see other TODO.
+ ADDFUNC1R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", varray());
ADDFUNC0R(BASIS, QUAT, Basis, get_rotation_quat, varray());
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, inverse, varray());
diff --git a/core/variant_internal.h b/core/variant_internal.h
new file mode 100644
index 0000000000..0e0a1e398f
--- /dev/null
+++ b/core/variant_internal.h
@@ -0,0 +1,118 @@
+/*************************************************************************/
+/* variant_internal.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VARIANT_INTERNAL_H
+#define VARIANT_INTERNAL_H
+
+#include "variant.h"
+
+// For use when you want to access the internal pointer of a Variant directly.
+// Use with caution. You need to be sure that the type is correct.
+class VariantInternal {
+public:
+ // Set type.
+ _FORCE_INLINE_ static void initialize(Variant *v, Variant::Type p_type) { v->type = p_type; }
+
+ // Atomic types.
+ _FORCE_INLINE_ static bool *get_bool(Variant *v) { return &v->_data._bool; }
+ _FORCE_INLINE_ static const bool *get_bool(const Variant *v) { return &v->_data._bool; }
+ _FORCE_INLINE_ static int64_t *get_int(Variant *v) { return &v->_data._int; }
+ _FORCE_INLINE_ static const int64_t *get_int(const Variant *v) { return &v->_data._int; }
+ _FORCE_INLINE_ static double *get_float(Variant *v) { return &v->_data._float; }
+ _FORCE_INLINE_ static const double *get_float(const Variant *v) { return &v->_data._float; }
+ _FORCE_INLINE_ static String *get_string(Variant *v) { return reinterpret_cast<String *>(v->_data._mem); }
+ _FORCE_INLINE_ static const String *get_string(const Variant *v) { return reinterpret_cast<const String *>(v->_data._mem); }
+
+ // Math types.
+ _FORCE_INLINE_ static Vector2 *get_vector2(Variant *v) { return reinterpret_cast<Vector2 *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector2 *get_vector2(const Variant *v) { return reinterpret_cast<const Vector2 *>(v->_data._mem); }
+ _FORCE_INLINE_ static Vector2i *get_vector2i(Variant *v) { return reinterpret_cast<Vector2i *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector2i *get_vector2i(const Variant *v) { return reinterpret_cast<const Vector2i *>(v->_data._mem); }
+ _FORCE_INLINE_ static Rect2 *get_rect2(Variant *v) { return reinterpret_cast<Rect2 *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Rect2 *get_rect2(const Variant *v) { return reinterpret_cast<const Rect2 *>(v->_data._mem); }
+ _FORCE_INLINE_ static Rect2i *get_rect2i(Variant *v) { return reinterpret_cast<Rect2i *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Rect2i *get_rect2i(const Variant *v) { return reinterpret_cast<const Rect2i *>(v->_data._mem); }
+ _FORCE_INLINE_ static Vector3 *get_vector3(Variant *v) { return reinterpret_cast<Vector3 *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return reinterpret_cast<const Vector3 *>(v->_data._mem); }
+ _FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return reinterpret_cast<Vector3i *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return reinterpret_cast<const Vector3i *>(v->_data._mem); }
+ _FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return v->_data._transform2d; }
+ _FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; }
+ _FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Plane *get_plane(const Variant *v) { return reinterpret_cast<const Plane *>(v->_data._mem); }
+ _FORCE_INLINE_ static Quat *get_quat(Variant *v) { return reinterpret_cast<Quat *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Quat *get_quat(const Variant *v) { return reinterpret_cast<const Quat *>(v->_data._mem); }
+ _FORCE_INLINE_ static ::AABB *get_aabb(Variant *v) { return v->_data._aabb; }
+ _FORCE_INLINE_ static const ::AABB *get_aabb(const Variant *v) { return v->_data._aabb; }
+ _FORCE_INLINE_ static Basis *get_basis(Variant *v) { return v->_data._basis; }
+ _FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; }
+ _FORCE_INLINE_ static Transform *get_transform(Variant *v) { return v->_data._transform; }
+ _FORCE_INLINE_ static const Transform *get_transform(const Variant *v) { return v->_data._transform; }
+
+ // Misc types.
+ _FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Color *get_color(const Variant *v) { return reinterpret_cast<const Color *>(v->_data._mem); }
+ _FORCE_INLINE_ static StringName *get_string_name(Variant *v) { return reinterpret_cast<StringName *>(v->_data._mem); }
+ _FORCE_INLINE_ static const StringName *get_string_name(const Variant *v) { return reinterpret_cast<const StringName *>(v->_data._mem); }
+ _FORCE_INLINE_ static NodePath *get_node_path(Variant *v) { return reinterpret_cast<NodePath *>(v->_data._mem); }
+ _FORCE_INLINE_ static const NodePath *get_node_path(const Variant *v) { return reinterpret_cast<const NodePath *>(v->_data._mem); }
+ _FORCE_INLINE_ static RID *get_rid(Variant *v) { return reinterpret_cast<RID *>(v->_data._mem); }
+ _FORCE_INLINE_ static const RID *get_rid(const Variant *v) { return reinterpret_cast<const RID *>(v->_data._mem); }
+ _FORCE_INLINE_ static Callable *get_callable(Variant *v) { return reinterpret_cast<Callable *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Callable *get_callable(const Variant *v) { return reinterpret_cast<const Callable *>(v->_data._mem); }
+ _FORCE_INLINE_ static Signal *get_signal(Variant *v) { return reinterpret_cast<Signal *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Signal *get_signal(const Variant *v) { return reinterpret_cast<const Signal *>(v->_data._mem); }
+ _FORCE_INLINE_ static Dictionary *get_dictionary(Variant *v) { return reinterpret_cast<Dictionary *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Dictionary *get_dictionary(const Variant *v) { return reinterpret_cast<const Dictionary *>(v->_data._mem); }
+ _FORCE_INLINE_ static Array *get_array(Variant *v) { return reinterpret_cast<Array *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Array *get_array(const Variant *v) { return reinterpret_cast<const Array *>(v->_data._mem); }
+
+ // Typed arrays.
+ _FORCE_INLINE_ static PackedByteArray *get_byte_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<uint8_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedByteArray *get_byte_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<uint8_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedInt32Array *get_int32_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<int32_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedInt32Array *get_int32_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<int32_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedInt64Array *get_int64_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<int64_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedInt64Array *get_int64_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<int64_t> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedFloat32Array *get_float32_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<float> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedFloat32Array *get_float32_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<float> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedFloat64Array *get_float64_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<double> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedFloat64Array *get_float64_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<double> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedStringArray *get_string_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<String> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedStringArray *get_string_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<String> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedVector2Array *get_vector2_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<Vector2> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedVector2Array *get_vector2_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<Vector2> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedVector3Array *get_vector3_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<Vector3> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedVector3Array *get_vector3_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<Vector3> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static PackedColorArray *get_color_array(Variant *v) { return &static_cast<Variant::PackedArrayRef<Color> *>(v->_data.packed_array)->array; }
+ _FORCE_INLINE_ static const PackedColorArray *get_color_array(const Variant *v) { return &static_cast<const Variant::PackedArrayRef<Color> *>(v->_data.packed_array)->array; }
+};
+
+#endif // VARIANT_INTERNAL_H
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 0c9a4a992a..ec4eea05bf 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -118,32 +118,32 @@
/* clang-format on */
-#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][Variant::VARIANT_MAX] = { \
- TYPES(PREFIX, OP_EQUAL), \
- TYPES(PREFIX, OP_NOT_EQUAL), \
- TYPES(PREFIX, OP_LESS), \
- TYPES(PREFIX, OP_LESS_EQUAL), \
- TYPES(PREFIX, OP_GREATER), \
- TYPES(PREFIX, OP_GREATER_EQUAL), \
- TYPES(PREFIX, OP_ADD), \
- TYPES(PREFIX, OP_SUBTRACT), \
- TYPES(PREFIX, OP_MULTIPLY), \
- TYPES(PREFIX, OP_DIVIDE), \
- TYPES(PREFIX, OP_NEGATE), \
- TYPES(PREFIX, OP_POSITIVE), \
- TYPES(PREFIX, OP_MODULE), \
- TYPES(PREFIX, OP_STRING_CONCAT), \
- TYPES(PREFIX, OP_SHIFT_LEFT), \
- TYPES(PREFIX, OP_SHIFT_RIGHT), \
- TYPES(PREFIX, OP_BIT_AND), \
- TYPES(PREFIX, OP_BIT_OR), \
- TYPES(PREFIX, OP_BIT_XOR), \
- TYPES(PREFIX, OP_BIT_NEGATE), \
- TYPES(PREFIX, OP_AND), \
- TYPES(PREFIX, OP_OR), \
- TYPES(PREFIX, OP_XOR), \
- TYPES(PREFIX, OP_NOT), \
- TYPES(PREFIX, OP_IN), \
+#define CASES(PREFIX) static const void *switch_table_##PREFIX[Variant::OP_MAX][Variant::VARIANT_MAX] = { \
+ TYPES(PREFIX, OP_EQUAL), \
+ TYPES(PREFIX, OP_NOT_EQUAL), \
+ TYPES(PREFIX, OP_LESS), \
+ TYPES(PREFIX, OP_LESS_EQUAL), \
+ TYPES(PREFIX, OP_GREATER), \
+ TYPES(PREFIX, OP_GREATER_EQUAL), \
+ TYPES(PREFIX, OP_ADD), \
+ TYPES(PREFIX, OP_SUBTRACT), \
+ TYPES(PREFIX, OP_MULTIPLY), \
+ TYPES(PREFIX, OP_DIVIDE), \
+ TYPES(PREFIX, OP_NEGATE), \
+ TYPES(PREFIX, OP_POSITIVE), \
+ TYPES(PREFIX, OP_MODULE), \
+ TYPES(PREFIX, OP_STRING_CONCAT), \
+ TYPES(PREFIX, OP_SHIFT_LEFT), \
+ TYPES(PREFIX, OP_SHIFT_RIGHT), \
+ TYPES(PREFIX, OP_BIT_AND), \
+ TYPES(PREFIX, OP_BIT_OR), \
+ TYPES(PREFIX, OP_BIT_XOR), \
+ TYPES(PREFIX, OP_BIT_NEGATE), \
+ TYPES(PREFIX, OP_AND), \
+ TYPES(PREFIX, OP_OR), \
+ TYPES(PREFIX, OP_XOR), \
+ TYPES(PREFIX, OP_NOT), \
+ TYPES(PREFIX, OP_IN), \
}
#define SWITCH(PREFIX, op, val) goto *switch_table_##PREFIX[op][val];
@@ -245,22 +245,22 @@ bool Variant::booleanize() const {
_RETURN(p_a._data.m_type); \
}
-#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) \
- _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) \
- _RETURN(p_a._data.m_type m_op p_b._data._float); \
- if (p_b.type == VECTOR2) \
- _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3) \
- _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR2I) \
- _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3I) \
- _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == VECTOR2) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR2I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2i *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3i *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
}
#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
@@ -4215,7 +4215,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
int split = csize / 2;
for (int i = 0; i < csize; i++) {
- CharType chr = ' ';
+ char32_t chr = ' ';
if (i < split) {
if (i < sa.length()) {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 74f4f32c0e..04cd4c1b9b 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -35,7 +35,7 @@
#include "core/os/keyboard.h"
#include "core/string_buffer.h"
-CharType VariantParser::StreamFile::get_char() {
+char32_t VariantParser::StreamFile::get_char() {
return f->get_8();
}
@@ -47,7 +47,7 @@ bool VariantParser::StreamFile::is_eof() const {
return f->eof_reached();
}
-CharType VariantParser::StreamString::get_char() {
+char32_t VariantParser::StreamString::get_char() {
if (pos > s.length()) {
return 0;
} else if (pos == s.length()) {
@@ -94,7 +94,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
bool string_name = false;
while (true) {
- CharType cchar;
+ char32_t cchar;
if (p_stream->saved) {
cchar = p_stream->saved;
p_stream->saved = 0;
@@ -145,7 +145,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
}
case ';': {
while (true) {
- CharType ch = p_stream->get_char();
+ char32_t ch = p_stream->get_char();
if (p_stream->is_eof()) {
r_token.type = TK_EOF;
return OK;
@@ -173,7 +173,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
StringBuffer<> color_str;
color_str += '#';
while (true) {
- CharType ch = p_stream->get_char();
+ char32_t ch = p_stream->get_char();
if (p_stream->is_eof()) {
r_token.type = TK_EOF;
return OK;
@@ -204,7 +204,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
case '"': {
String str;
while (true) {
- CharType ch = p_stream->get_char();
+ char32_t ch = p_stream->get_char();
if (ch == 0) {
r_err_str = "Unterminated String";
@@ -214,13 +214,13 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
break;
} else if (ch == '\\') {
//escaped characters...
- CharType next = p_stream->get_char();
+ char32_t next = p_stream->get_char();
if (next == 0) {
r_err_str = "Unterminated String";
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -241,7 +241,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
case 'u': {
//hex number
for (int j = 0; j < 4; j++) {
- CharType c = p_stream->get_char();
+ char32_t c = p_stream->get_char();
if (c == 0) {
r_err_str = "Unterminated String";
r_token.type = TK_ERROR;
@@ -252,7 +252,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType v;
+ char32_t v;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -321,7 +321,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
cchar = p_stream->get_char();
}
- CharType c = cchar;
+ char32_t c = cchar;
bool exp_sign = false;
bool exp_beg = false;
bool is_float = false;
@@ -421,7 +421,7 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings,
String accum;
while (true) {
- CharType c = p_stream->get_char();
+ char32_t c = p_stream->get_char();
if (p_stream->is_eof()) {
r_err_str = "Unexpected EOF while parsing old-style project.godot construct";
@@ -1206,7 +1206,7 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
r_tag.fields.clear();
while (true) {
- CharType c = p_stream->get_char();
+ char32_t c = p_stream->get_char();
if (p_stream->is_eof()) {
r_err_str = "Unexpected EOF while parsing simple tag";
return ERR_PARSE_ERROR;
@@ -1305,7 +1305,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
String what;
while (true) {
- CharType c;
+ char32_t c;
if (p_stream->saved) {
c = p_stream->saved;
p_stream->saved = 0;
@@ -1320,7 +1320,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
if (c == ';') { //comment
while (true) {
- CharType ch = p_stream->get_char();
+ char32_t ch = p_stream->get_char();
if (p_stream->is_eof()) {
return ERR_FILE_EOF;
}
@@ -1608,10 +1608,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n");
+ } else {
+ p_store_string_func(p_store_string_ud, "\n");
}
}
- p_store_string_func(p_store_string_ud, "\n}");
+ p_store_string_func(p_store_string_ud, "}");
} break;
case Variant::ARRAY: {
diff --git a/core/variant_parser.h b/core/variant_parser.h
index b55d7b2df0..12329e2db6 100644
--- a/core/variant_parser.h
+++ b/core/variant_parser.h
@@ -38,11 +38,11 @@
class VariantParser {
public:
struct Stream {
- virtual CharType get_char() = 0;
+ virtual char32_t get_char() = 0;
virtual bool is_utf8() const = 0;
virtual bool is_eof() const = 0;
- CharType saved = 0;
+ char32_t saved = 0;
Stream() {}
virtual ~Stream() {}
@@ -51,7 +51,7 @@ public:
struct StreamFile : public Stream {
FileAccess *f = nullptr;
- virtual CharType get_char();
+ virtual char32_t get_char();
virtual bool is_utf8() const;
virtual bool is_eof() const;
@@ -62,7 +62,7 @@ public:
String s;
int pos = 0;
- virtual CharType get_char();
+ virtual char32_t get_char();
virtual bool is_utf8() const;
virtual bool is_eof() const;
diff --git a/core/vector.h b/core/vector.h
index 5fb630c21c..5a61f0eae3 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -82,7 +82,7 @@ public:
_FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
_FORCE_INLINE_ T get(int p_index) { return _cowdata.get(p_index); }
- _FORCE_INLINE_ const T get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ const T &get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 570bf191c7..2b1770f12b 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -356,16 +356,16 @@
Right Direction key.
</constant>
<constant name="KEY_BACK" value="16777280" enum="KeyList">
- Back key.
+ Media back key. Not to be confused with the Back button on an Android device.
</constant>
<constant name="KEY_FORWARD" value="16777281" enum="KeyList">
- Forward key.
+ Media forward key.
</constant>
<constant name="KEY_STOP" value="16777282" enum="KeyList">
- Stop key.
+ Media stop key.
</constant>
<constant name="KEY_REFRESH" value="16777283" enum="KeyList">
- Refresh key.
+ Media refresh key.
</constant>
<constant name="KEY_VOLUMEDOWN" value="16777284" enum="KeyList">
Volume down key.
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index ae80abc5d2..faa380ff33 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -4,10 +4,12 @@
Axis-Aligned Bounding Box.
</brief_description>
<description>
- AABB consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
+ [AABB] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
+ It uses floating-point coordinates. The 2D counterpart to [AABB] is [Rect2].
+ [b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses integer coordinates.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="AABB">
diff --git a/doc/classes/AESContext.xml b/doc/classes/AESContext.xml
index ff433370bd..f577bab992 100644
--- a/doc/classes/AESContext.xml
+++ b/doc/classes/AESContext.xml
@@ -5,7 +5,8 @@
</brief_description>
<description>
This class provides access to AES encryption/decryption of raw data. Both AES-ECB and AES-CBC mode are supported.
- [codeblock]
+ [codeblocks]
+ [gdscript]
extends Node
var aes = AESContext.new()
@@ -35,7 +36,45 @@
aes.finish()
# Check CBC
assert(decrypted == data.to_utf8())
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ using Godot;
+ using System;
+ using System.Diagnostics;
+
+ public class Example : Node
+ {
+ public AESContext Aes = new AESContext();
+ public override void _Ready()
+ {
+ string key = "My secret key!!!"; // Key must be either 16 or 32 bytes.
+ string data = "My secret text!!"; // Data size must be multiple of 16 bytes, apply padding if needed.
+ // Encrypt ECB
+ Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8());
+ byte[] encrypted = Aes.Update(data.ToUTF8());
+ Aes.Finish();
+ // Decrypt ECB
+ Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8());
+ byte[] decrypted = Aes.Update(encrypted);
+ Aes.Finish();
+ // Check ECB
+ Debug.Assert(decrypted == data.ToUTF8());
+
+ string iv = "My secret iv!!!!"; // IV must be of exactly 16 bytes.
+ // Encrypt CBC
+ Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8(), iv.ToUTF8());
+ encrypted = Aes.Update(data.ToUTF8());
+ Aes.Finish();
+ // Decrypt CBC
+ Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8(), iv.ToUTF8());
+ decrypted = Aes.Update(encrypted);
+ Aes.Finish();
+ // Check CBC
+ Debug.Assert(decrypted == data.ToUTF8());
+ }
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index 2695e86f47..0cd7d3dc25 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -7,7 +7,8 @@
A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting short paths among vertices (points), passing through a given set of edges (segments). It enjoys widespread use due to its performance and accuracy. Godot's A* implementation uses points in three-dimensional space and Euclidean distances by default.
You must add points manually with [method add_point] and create segments manually with [method connect_points]. Then you can test if there is a path between two points with the [method are_points_connected] function, get a path containing indices by [method get_id_path], or one containing actual coordinates with [method get_point_path].
It is also possible to use non-Euclidean distances. To do so, create a class that extends [code]AStar[/code] and override methods [method _compute_cost] and [method _estimate_cost]. Both take two indices and return a length, as is shown in the following example.
- [codeblock]
+ [codeblocks]
+ [gdscript]
class MyAStar:
extends AStar
@@ -16,7 +17,21 @@
func _estimate_cost(u, v):
return min(0, abs(u - v) - 1)
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public class MyAStar : AStar
+ {
+ public override float _ComputeCost(int u, int v)
+ {
+ return Mathf.Abs(u - v);
+ }
+ public override float _EstimateCost(int u, int v)
+ {
+ return Mathf.Min(0, Mathf.Abs(u - v) - 1);
+ }
+ }
+ [/csharp]
+ [/codeblocks]
[method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) &lt;= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information.
</description>
<tutorials>
@@ -57,10 +72,16 @@
</argument>
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
- [codeblock]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar();
+ astar.AddPoint(1, new Vector3(1, 0, 0), 4); // Adds the point (1, 0, 0) with weight_scale 4 and id 1
+ [/csharp]
+ [/codeblocks]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
</method>
@@ -95,12 +116,20 @@
</argument>
<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]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar();
+ astar.AddPoint(1, new Vector3(1, 1, 0));
+ astar.AddPoint(2, new Vector3(0, 5, 0));
+ astar.ConnectPoints(1, 2, false);
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="disconnect_points">
@@ -142,13 +171,22 @@
</argument>
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
- [codeblock]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar();
+ astar.AddPoint(1, new Vector3(0, 0, 0));
+ astar.AddPoint(2, new Vector3(0, 5, 0));
+ astar.ConnectPoints(1, 2);
+ Vector3 res = astar.GetClosestPositionInSegment(new Vector3(3, 3, 0)); // Returns (0, 3, 0)
+ [/csharp]
+ [/codeblocks]
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>
</method>
@@ -161,7 +199,8 @@
</argument>
<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]
+ [codeblocks]
+ [gdscript]
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
@@ -174,7 +213,20 @@
astar.connect_points(1, 4, false)
var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar();
+ astar.AddPoint(1, new Vector3(0, 0, 0));
+ astar.AddPoint(2, new Vector3(0, 1, 0), 1); // Default weight is 1
+ astar.AddPoint(3, new Vector3(1, 1, 0));
+ astar.AddPoint(4, new Vector3(2, 0, 0));
+ astar.ConnectPoints(1, 2, false);
+ astar.ConnectPoints(2, 3, false);
+ astar.ConnectPoints(4, 3, false);
+ astar.ConnectPoints(1, 4, false);
+ int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
+ [/csharp]
+ [/codeblocks]
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>
@@ -192,7 +244,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the connection with the given point.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(0, 0, 0))
astar.add_point(2, Vector3(0, 1, 0))
@@ -203,7 +256,19 @@
astar.connect_points(1, 3, true)
var neighbors = astar.get_point_connections(1) # Returns [2, 3]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar();
+ astar.AddPoint(1, new Vector3(0, 0, 0));
+ astar.AddPoint(2, new Vector3(0, 1, 0));
+ astar.AddPoint(3, new Vector3(1, 1, 0));
+ astar.AddPoint(4, new Vector3(2, 0, 0));
+ astar.ConnectPoints(1, 2, true);
+ astar.ConnectPoints(1, 3, true);
+
+ int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="get_point_count" qualifiers="const">
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 622d336ef6..1540d8dacc 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -44,10 +44,16 @@
</argument>
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
- [codeblock]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar2D();
+ astar.AddPoint(1, new Vector2(1, 0), 4); // Adds the point (1, 0) with weight_scale 4 and id 1
+ [/csharp]
+ [/codeblocks]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
</method>
@@ -80,12 +86,20 @@
</argument>
<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]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar2D();
+ astar.AddPoint(1, new Vector2(1, 1));
+ astar.AddPoint(2, new Vector2(0, 5));
+ astar.ConnectPoints(1, 2, false);
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="disconnect_points">
@@ -125,13 +139,22 @@
</argument>
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
- [codeblock]
+ [codeblocks]
+ [gdscript]
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]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar2D();
+ astar.AddPoint(1, new Vector2(0, 0));
+ astar.AddPoint(2, new Vector2(0, 5));
+ astar.ConnectPoints(1, 2);
+ Vector2 res = astar.GetClosestPositionInSegment(new Vector2(3, 3)); // Returns (0, 3)
+ [/csharp]
+ [/codeblocks]
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>
</method>
@@ -144,7 +167,8 @@
</argument>
<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]
+ [codeblocks]
+ [gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(0, 0))
astar.add_point(2, Vector2(0, 1), 1) # Default weight is 1
@@ -157,7 +181,21 @@
astar.connect_points(1, 4, false)
var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar2D();
+ astar.AddPoint(1, new Vector2(0, 0));
+ astar.AddPoint(2, new Vector2(0, 1), 1); // Default weight is 1
+ astar.AddPoint(3, new Vector2(1, 1));
+ astar.AddPoint(4, new Vector2(2, 0));
+
+ astar.ConnectPoints(1, 2, false);
+ astar.ConnectPoints(2, 3, false);
+ astar.ConnectPoints(4, 3, false);
+ astar.ConnectPoints(1, 4, false);
+ int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
+ [/csharp]
+ [/codeblocks]
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>
@@ -175,7 +213,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the connection with the given point.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(0, 0))
astar.add_point(2, Vector2(0, 1))
@@ -186,7 +225,20 @@
astar.connect_points(1, 3, true)
var neighbors = astar.get_point_connections(1) # Returns [2, 3]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var astar = new AStar2D();
+ astar.AddPoint(1, new Vector2(0, 0));
+ astar.AddPoint(2, new Vector2(0, 1));
+ astar.AddPoint(3, new Vector2(1, 1));
+ astar.AddPoint(4, new Vector2(2, 0));
+
+ astar.ConnectPoints(1, 2, true);
+ astar.ConnectPoints(1, 3, true);
+
+ int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="get_point_count" qualifiers="const">
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index 6b1864b679..e5eb216062 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -76,6 +76,7 @@
<signals>
<signal name="cancelled">
<description>
+ Emitted when the dialog is closed or the button created with [method add_cancel] is pressed.
</description>
</signal>
<signal name="confirmed">
diff --git a/doc/classes/AnimatedSprite2D.xml b/doc/classes/AnimatedSprite2D.xml
index 7a992d0c03..e23a4fe9f8 100644
--- a/doc/classes/AnimatedSprite2D.xml
+++ b/doc/classes/AnimatedSprite2D.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Animations are created using a [SpriteFrames] resource, which can be configured in the editor via the SpriteFrames panel.
+ [b]Note:[/b] You can associate a set of normal or specular maps by creating additional [SpriteFrames] resources with a [code]_normal[/code] or [code]_specular[/code] suffix. For example, having 3 [SpriteFrames] resources [code]run[/code], [code]run_normal[/code], and [code]run_specular[/code] will make it so the [code]run[/code] animation uses normal and specular maps.
</description>
<tutorials>
<link title="2D Sprite animation">https://docs.godotengine.org/en/latest/tutorials/2d/2d_sprite_animation.html</link>
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index 68f0a630ef..9529c60771 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -5,7 +5,8 @@
</brief_description>
<description>
An Animation resource contains data used to animate everything in the engine. Animations are divided into tracks, and each track must be linked to a node. The state of that node can be changed through time, by adding timed keys (events) to the track.
- [codeblock]
+ [codeblocks]
+ [gdscript]
# This creates an animation that makes the node "Enemy" move to the right by
# 100 pixels in 0.5 seconds.
var animation = Animation.new()
@@ -13,11 +14,21 @@
animation.track_set_path(track_index, "Enemy:position:x")
animation.track_insert_key(track_index, 0.0, 0)
animation.track_insert_key(track_index, 0.5, 100)
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // This creates an animation that makes the node "Enemy" move to the right by
+ // 100 pixels in 0.5 seconds.
+ var animation = new Animation();
+ int trackIndex = animation.AddTrack(Animation.TrackType.Value);
+ animation.TrackSetPath(trackIndex, "Enemy:position:x");
+ animation.TrackInsertKey(trackIndex, 0.0f, 0);
+ animation.TrackInsertKey(trackIndex, 0.5f, 100);
+ [/csharp]
+ [/codeblocks]
Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/index.html</link>
+ <link title="Animation tutorial index">https://docs.godotengine.org/en/latest/tutorials/animation/index.html</link>
</tutorials>
<methods>
<method name="add_track">
diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml
index 3d6ebd5934..8204b456d9 100644
--- a/doc/classes/AnimationNode.xml
+++ b/doc/classes/AnimationNode.xml
@@ -8,7 +8,7 @@
Inherit this when creating nodes mainly for use in [AnimationNodeBlendTree], otherwise [AnimationRootNode] should be used instead.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="add_input">
diff --git a/doc/classes/AnimationNodeAdd2.xml b/doc/classes/AnimationNodeAdd2.xml
index 48983a624e..63127ade9a 100644
--- a/doc/classes/AnimationNodeAdd2.xml
+++ b/doc/classes/AnimationNodeAdd2.xml
@@ -7,7 +7,7 @@
A resource to add to an [AnimationNodeBlendTree]. Blends two animations additively based on an amount value in the [code][0.0, 1.0][/code] range.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeAdd3.xml b/doc/classes/AnimationNodeAdd3.xml
index 1bfebc91fc..94a6ae4221 100644
--- a/doc/classes/AnimationNodeAdd3.xml
+++ b/doc/classes/AnimationNodeAdd3.xml
@@ -11,7 +11,7 @@
- A +add animation to blend with when the blend amount is in the [code][0.0, 1.0][/code] range
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeAnimation.xml b/doc/classes/AnimationNodeAnimation.xml
index ab44148c15..d8ac5413fd 100644
--- a/doc/classes/AnimationNodeAnimation.xml
+++ b/doc/classes/AnimationNodeAnimation.xml
@@ -7,7 +7,7 @@
A resource to add to an [AnimationNodeBlendTree]. Only features one output set using the [member animation] property. Use it as an input for [AnimationNode] that blend animations together.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeBlend2.xml b/doc/classes/AnimationNodeBlend2.xml
index 2b56167225..e2cd12e685 100644
--- a/doc/classes/AnimationNodeBlend2.xml
+++ b/doc/classes/AnimationNodeBlend2.xml
@@ -7,7 +7,7 @@
A resource to add to an [AnimationNodeBlendTree]. Blends two animations linearly based on an amount value in the [code][0.0, 1.0][/code] range.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeBlend3.xml b/doc/classes/AnimationNodeBlend3.xml
index 5a306a225d..7c81b37663 100644
--- a/doc/classes/AnimationNodeBlend3.xml
+++ b/doc/classes/AnimationNodeBlend3.xml
@@ -11,7 +11,7 @@
- A +blend animation to blend with when the blend amount is in the [code][0.0, 1.0][/code] range
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeBlendSpace1D.xml b/doc/classes/AnimationNodeBlendSpace1D.xml
index 6e82f0afb7..263b59910b 100644
--- a/doc/classes/AnimationNodeBlendSpace1D.xml
+++ b/doc/classes/AnimationNodeBlendSpace1D.xml
@@ -10,7 +10,7 @@
You can set the extents of the axis using the [member min_space] and [member max_space].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="add_blend_point">
diff --git a/doc/classes/AnimationNodeBlendSpace2D.xml b/doc/classes/AnimationNodeBlendSpace2D.xml
index f8680ba8ec..460c11cc5e 100644
--- a/doc/classes/AnimationNodeBlendSpace2D.xml
+++ b/doc/classes/AnimationNodeBlendSpace2D.xml
@@ -9,7 +9,7 @@
You can add vertices to the blend space with [method add_blend_point] and automatically triangulate it by setting [member auto_triangles] to [code]true[/code]. Otherwise, use [method add_triangle] and [method remove_triangle] to create up the blend space by hand.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="add_blend_point">
diff --git a/doc/classes/AnimationNodeBlendTree.xml b/doc/classes/AnimationNodeBlendTree.xml
index 4a34d75ff9..8f87ce453f 100644
--- a/doc/classes/AnimationNodeBlendTree.xml
+++ b/doc/classes/AnimationNodeBlendTree.xml
@@ -7,7 +7,7 @@
This node may contain a sub-tree of any other blend type nodes, such as mix, blend2, blend3, one shot, etc. This is one of the most commonly used roots.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="add_node">
diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml
index 4ba0b82df6..d5793e5839 100644
--- a/doc/classes/AnimationNodeOneShot.xml
+++ b/doc/classes/AnimationNodeOneShot.xml
@@ -7,7 +7,7 @@
A resource to add to an [AnimationNodeBlendTree]. This node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="get_mix_mode" qualifiers="const">
diff --git a/doc/classes/AnimationNodeOutput.xml b/doc/classes/AnimationNodeOutput.xml
index 38b05eb650..7640f4dcfa 100644
--- a/doc/classes/AnimationNodeOutput.xml
+++ b/doc/classes/AnimationNodeOutput.xml
@@ -6,7 +6,7 @@
<description>
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeStateMachine.xml b/doc/classes/AnimationNodeStateMachine.xml
index 3b351a3345..e08e288c59 100644
--- a/doc/classes/AnimationNodeStateMachine.xml
+++ b/doc/classes/AnimationNodeStateMachine.xml
@@ -6,13 +6,19 @@
<description>
Contains multiple nodes representing animation states, connected in a graph. Node transitions can be configured to happen automatically or via code, using a shortest-path algorithm. Retrieve the [AnimationNodeStateMachinePlayback] object from the [AnimationTree] node to control it programmatically.
[b]Example:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
var state_machine = $AnimationTree.get("parameters/playback")
state_machine.travel("some_state")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var stateMachine = GetNode&lt;AnimationTree&gt;("AnimationTree").Get("parameters/playback") as AnimationNodeStateMachinePlayback;
+ stateMachine.Travel("some_state");
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="add_node">
diff --git a/doc/classes/AnimationNodeStateMachinePlayback.xml b/doc/classes/AnimationNodeStateMachinePlayback.xml
index f4b89a5086..60ff425cdb 100644
--- a/doc/classes/AnimationNodeStateMachinePlayback.xml
+++ b/doc/classes/AnimationNodeStateMachinePlayback.xml
@@ -6,13 +6,19 @@
<description>
Allows control of [AnimationTree] state machines created with [AnimationNodeStateMachine]. Retrieve with [code]$AnimationTree.get("parameters/playback")[/code].
[b]Example:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
var state_machine = $AnimationTree.get("parameters/playback")
state_machine.travel("some_state")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var stateMachine = GetNode&lt;AnimationTree&gt;("AnimationTree").Get("parameters/playback") as AnimationNodeStateMachinePlayback;
+ stateMachine.Travel("some_state");
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="get_current_node" qualifiers="const">
diff --git a/doc/classes/AnimationNodeStateMachineTransition.xml b/doc/classes/AnimationNodeStateMachineTransition.xml
index f0b7cc4099..2f0ebd7de6 100644
--- a/doc/classes/AnimationNodeStateMachineTransition.xml
+++ b/doc/classes/AnimationNodeStateMachineTransition.xml
@@ -5,16 +5,21 @@
<description>
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
<members>
<member name="advance_condition" type="StringName" setter="set_advance_condition" getter="get_advance_condition" default="@&quot;&quot;">
Turn on auto advance when this condition is set. The provided name will become a boolean parameter on the [AnimationTree] that can be controlled from code (see [url=https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html#controlling-from-code][/url]). For example, if [member AnimationTree.tree_root] is an [AnimationNodeStateMachine] and [member advance_condition] is set to [code]"idle"[/code]:
- [codeblock]
- $animation_tree["parameters/conditions/idle"] = is_on_floor and (linear_velocity.x == 0)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ $animation_tree.set("parameters/conditions/idle", is_on_floor and (linear_velocity.x == 0))
+ [/gdscript]
+ [csharp]
+ GetNode&lt;AnimationTree&gt;("animation_tree").Set("parameters/conditions/idle", IsOnFloor &amp;&amp; (LinearVelocity.x == 0));
+ [/csharp]
+ [/codeblocks]
</member>
<member name="auto_advance" type="bool" setter="set_auto_advance" getter="has_auto_advance" default="false">
Turn on the transition automatically when this state is reached. This works best with [constant SWITCH_MODE_AT_END].
diff --git a/doc/classes/AnimationNodeTimeScale.xml b/doc/classes/AnimationNodeTimeScale.xml
index 5c2e6cb692..334fdb0b95 100644
--- a/doc/classes/AnimationNodeTimeScale.xml
+++ b/doc/classes/AnimationNodeTimeScale.xml
@@ -7,7 +7,7 @@
Allows scaling the speed of the animation (or reversing it) in any children nodes. Setting it to 0 will pause the animation.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeTimeSeek.xml b/doc/classes/AnimationNodeTimeSeek.xml
index 0fef106da5..eb5335c792 100644
--- a/doc/classes/AnimationNodeTimeSeek.xml
+++ b/doc/classes/AnimationNodeTimeSeek.xml
@@ -7,7 +7,7 @@
This node can be used to cause a seek command to happen to any sub-children of the graph. After setting the time, this value returns to -1.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml
index 11250c5b17..8338f0d39a 100644
--- a/doc/classes/AnimationNodeTransition.xml
+++ b/doc/classes/AnimationNodeTransition.xml
@@ -7,7 +7,7 @@
Simple state machine for cases which don't require a more advanced [AnimationNodeStateMachine]. Animations can be connected to the inputs and transition times can be specified.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
<method name="get_input_caption" qualifiers="const">
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index 6267a5a0a9..ac91272e00 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -9,9 +9,8 @@
Updating the target properties of animations occurs at process time.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/animations.html</link>
<link title="2D Sprite animation">https://docs.godotengine.org/en/latest/tutorials/2d/2d_sprite_animation.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/index.html</link>
+ <link title="Animation tutorial index">https://docs.godotengine.org/en/latest/tutorials/animation/index.html</link>
</tutorials>
<methods>
<method name="add_animation">
@@ -236,7 +235,8 @@
The name of the animation to play when the scene loads.
</member>
<member name="current_animation" type="String" setter="set_current_animation" getter="get_current_animation" default="&quot;&quot;">
- The name of the current animation, "" if not playing anything. When being set, does not restart the animation. See also [method play].
+ The name of the currently playing animation. If no animation is playing, the property's value is an empty string. Changing this value does not restart the animation. See [method play] for more information on playing animations.
+ [b]Note[/b]: while this property appears in the inspector, it's not meant to be edited and it's not saved in the scene. This property is mainly used to get the currently playing animation, and internally for animation playback tracks. For more information, see [Animation].
</member>
<member name="current_animation_length" type="float" setter="" getter="get_current_animation_length">
The length (in seconds) of the currently being played animation.
diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml
index dd04f4ce3f..cc8e83f509 100644
--- a/doc/classes/AnimationTree.xml
+++ b/doc/classes/AnimationTree.xml
@@ -7,8 +7,8 @@
Note: When linked with an [AnimationPlayer], several properties and methods of the corresponding [AnimationPlayer] will not function as expected. Playback and transitions should be handled using only the [AnimationTree] and its constituent [AnimationNode](s). The [AnimationPlayer] node should be used solely for adding, deleting, and editing animations.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
- <link>https://github.com/godotengine/tps-demo</link>
+ <link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
+ <link title="Third-person shooter demo code repository">https://github.com/godotengine/tps-demo</link>
</tutorials>
<methods>
<method name="advance">
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index 4190cbe6b9..e98c0af0d9 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -7,7 +7,7 @@
2D area that detects [CollisionObject2D] nodes overlapping, entering, or exiting. Can also alter or override local physics parameters (gravity, damping).
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/using_area_2d.html</link>
+ <link title="Using Area2D">https://docs.godotengine.org/en/latest/tutorials/physics/using_area_2d.html</link>
</tutorials>
<methods>
<method name="get_collision_layer_bit" qualifiers="const">
@@ -97,10 +97,10 @@
If [code]true[/code], the area's audio bus overrides the default audio bus.
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
- The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask].
+ The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask]. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this area scans to determine collision detection.
+ The physics layers this area scans to determine collision detection. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="gravity" type="float" setter="set_gravity" getter="get_gravity" default="98.0">
The area's gravity intensity (ranges from -1024 to 1024). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction.
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index a94cecd879..ad9eff3a64 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -96,10 +96,10 @@
If [code]true[/code], the area's audio bus overrides the default audio bus.
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
- The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask].
+ The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask]. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this area scans to determine collision detection.
+ The physics layers this area scans to determine collision detection. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="gravity" type="float" setter="set_gravity" getter="get_gravity" default="9.8">
The area's gravity intensity (ranges from -1024 to 1024). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction.
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 61df5e092e..87b7443a8a 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -6,20 +6,38 @@
<description>
Generic array which can contain several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 the second to last, etc.).
[b]Example:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
var array = ["One", 2, 3, "Four"]
print(array[0]) # One.
print(array[2]) # 3.
print(array[-1]) # Four.
array[2] = "Three"
print(array[-2]) # Three.
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var array = new Godot.Collections.Array{"One", 2, 3, "Four"};
+ GD.Print(array[0]); // One.
+ GD.Print(array[2]); // 3.
+ GD.Print(array[array.Count - 1]); // Four.
+ array[2] = "Three";
+ GD.Print(array[array.Count - 2]); // Three.
+ [/csharp]
+ [/codeblocks]
Arrays can be concatenated using the [code]+[/code] operator:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var array1 = ["One", 2]
var array2 = [3, "Four"]
print(array1 + array2) # ["One", 2, 3, "Four"]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // Array concatenation is not possible with C# arrays, but is with Godot.Collections.Array.
+ var array1 = new Godot.Collections.Array("One", 2);
+ var array2 = new Godot.Collections.Array(3, "Four");
+ GD.Print(array1 + array2); // Prints [One, 2, 3, Four]
+ [/csharp]
+ [/codeblocks]
[b]Note:[/b] Arrays are always passed by reference. To get a copy of an array which can be modified independently of the original array, use [method duplicate].
</description>
<tutorials>
@@ -119,7 +137,8 @@
<return type="Variant">
</return>
<description>
- Returns the last element of the array. Throws an error and returns [code]null[/code] if the array is empty.
+ Returns the last element of the array. Prints an error and returns [code]null[/code] if the array is empty.
+ [b]Note:[/b] Calling this function is not the same as writing [code]array[-1][/code]. If the array is empty, accessing by index will pause project execution when running from the editor.
</description>
</method>
<method name="bsearch">
@@ -216,7 +235,8 @@
<return type="Variant">
</return>
<description>
- Returns the first element of the array. Throws an error and returns [code]null[/code] if the array is empty.
+ Returns the first element of the array. Prints an error and returns [code]null[/code] if the array is empty.
+ [b]Note:[/b] Calling this function is not the same as writing [code]array[0][/code]. If the array is empty, accessing by index will pause project execution when running from the editor.
</description>
</method>
<method name="has">
@@ -226,18 +246,39 @@
</argument>
<description>
Returns [code]true[/code] if the array contains the given value.
- [codeblock]
+ [codeblocks]
+ [gdscript]
print(["inside", 7].has("inside")) # True
print(["inside", 7].has("outside")) # False
print(["inside", 7].has(7)) # True
print(["inside", 7].has("7")) # False
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var arr = new Godot.Collections.Array{"inside", 7};
+ // has is renamed to Contains
+ GD.Print(arr.Contains("inside")); // True
+ GD.Print(arr.Contains("outside")); // False
+ GD.Print(arr.Contains(7)); // True
+ GD.Print(arr.Contains("7")); // False
+ [/csharp]
+ [/codeblocks]
+
[b]Note:[/b] This is equivalent to using the [code]in[/code] operator as follows:
- [codeblock]
+ [codeblocks]
+ [gdscript]
# Will evaluate to `true`.
if 2 in [2, 4, 6, 8]:
- pass
- [/codeblock]
+ print("Containes!")
+ [/gdscript]
+ [csharp]
+ // As there is no "in" keyword in C#, you have to use Contains
+ var array = new Godot.Collections.Array{2, 4, 6, 8};
+ if (array.Contains(2))
+ {
+ GD.Print("Containes!");
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="hash">
@@ -283,14 +324,14 @@
<return type="Variant">
</return>
<description>
- Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty.
+ Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message.
</description>
</method>
<method name="pop_front">
<return type="Variant">
</return>
<description>
- Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty.
+ Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, without printing an error message.
</description>
</method>
<method name="push_back">
@@ -317,7 +358,7 @@
<argument index="0" name="position" type="int">
</argument>
<description>
- Removes an element from the array by index.
+ Removes an element from the array by index. If the index does not exist in the array, nothing happens.
</description>
</method>
<method name="resize">
@@ -375,11 +416,16 @@
<description>
Sorts the array.
[b]Note:[/b] Strings are sorted in alphabetical order (as opposed to natural order). This may lead to unexpected behavior when sorting an array of strings ending with a sequence of numbers. Consider the following example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var strings = ["string1", "string2", "string10", "string11"]
strings.sort()
print(strings) # Prints [string1, string10, string11, string2]
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // There is no sort support for Godot.Collections.Array
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="sort_custom">
@@ -392,7 +438,8 @@
<description>
Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
[b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
- [codeblock]
+ [codeblocks]
+ [gdscript]
class MyCustomSorter:
static func sort_ascending(a, b):
if a[0] &lt; b[0]:
@@ -402,7 +449,11 @@
var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]]
my_items.sort_custom(MyCustomSorter, "sort_ascending")
print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]].
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // There is no custom sort support for Godot.Collections.Array
+ [/csharp]
+ [/codeblocks]
</description>
</method>
</methods>
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index b45716544a..4edf69ccb2 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -6,27 +6,48 @@
<description>
The [ArrayMesh] is used to construct a [Mesh] by specifying the attributes as arrays.
The most basic example is the creation of a single triangle:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var vertices = PackedVector3Array()
vertices.push_back(Vector3(0, 1, 0))
vertices.push_back(Vector3(1, 0, 0))
vertices.push_back(Vector3(0, 0, 1))
+
# Initialize the ArrayMesh.
var arr_mesh = ArrayMesh.new()
var arrays = []
arrays.resize(ArrayMesh.ARRAY_MAX)
arrays[ArrayMesh.ARRAY_VERTEX] = vertices
+
# Create the Mesh.
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
var m = MeshInstance3D.new()
m.mesh = arr_mesh
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var vertices = new Godot.Collections.Array&lt;Vector3&gt;();
+ vertices.Add(new Vector3(0, 1, 0));
+ vertices.Add(new Vector3(1, 0, 0));
+ vertices.Add(new Vector3(0, 0, 1));
+
+ // Initialize the ArrayMesh.
+ var arrMesh = new ArrayMesh();
+ var arrays = new Godot.Collections.Array();
+ arrays.Resize((int)ArrayMesh.ArrayType.Max);
+ arrays[(int)ArrayMesh.ArrayType.Vertex] = vertices;
+
+ // Create the Mesh.
+ arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
+ var m = new MeshInstance();
+ m.Mesh = arrMesh;
+ [/csharp]
+ [/codeblocks]
The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.
See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/arraymesh.html</link>
+ <link title="Procedural geometry using the ArrayMesh">https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/arraymesh.html</link>
</tutorials>
<methods>
<method name="add_blend_shape">
diff --git a/doc/classes/AudioEffectDistortion.xml b/doc/classes/AudioEffectDistortion.xml
index 3cfeaadb23..24a145b0f3 100644
--- a/doc/classes/AudioEffectDistortion.xml
+++ b/doc/classes/AudioEffectDistortion.xml
@@ -2,13 +2,14 @@
<class name="AudioEffectDistortion" inherits="AudioEffect" version="4.0">
<brief_description>
Adds a distortion audio effect to an Audio bus.
- Modify the sound to make it dirty.
+ Modify the sound to make it distorted.
</brief_description>
<description>
- Modify the sound and make it dirty. Different types are available: clip, tan, lo-fi (bit crushing), overdrive, or waveshape.
+ Different types are available: clip, tan, lo-fi (bit crushing), overdrive, or waveshape.
By distorting the waveform the frequency content change, which will often make the sound "crunchy" or "abrasive". For games, it can simulate sound coming from some saturated device or speaker very efficiently.
</description>
<tutorials>
+ <link title="Audio buses">https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AudioEffectFilter.xml b/doc/classes/AudioEffectFilter.xml
index f548fb49cc..293848d204 100644
--- a/doc/classes/AudioEffectFilter.xml
+++ b/doc/classes/AudioEffectFilter.xml
@@ -7,6 +7,7 @@
Allows frequencies other than the [member cutoff_hz] to pass.
</description>
<tutorials>
+ <link title="Audio buses">https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
</tutorials>
<methods>
</methods>
@@ -20,7 +21,7 @@
Gain amount of the frequencies after the filter.
</member>
<member name="resonance" type="float" setter="set_resonance" getter="get_resonance" default="0.5">
- Amount of boost in the overtones near the cutoff frequency.
+ Amount of boost in the frequency range near the cutoff frequency.
</member>
</members>
<constants>
diff --git a/doc/classes/AudioEffectHighShelfFilter.xml b/doc/classes/AudioEffectHighShelfFilter.xml
index cf620e4417..4ba31f9fc8 100644
--- a/doc/classes/AudioEffectHighShelfFilter.xml
+++ b/doc/classes/AudioEffectHighShelfFilter.xml
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AudioEffectHighShelfFilter" inherits="AudioEffectFilter" version="4.0">
<brief_description>
+ Reduces all frequencies above the [member AudioEffectFilter.cutoff_hz].
</brief_description>
<description>
</description>
<tutorials>
+ <link title="Audio buses">https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AudioEffectLowShelfFilter.xml b/doc/classes/AudioEffectLowShelfFilter.xml
index 7cf09b0f05..078e7bf1a1 100644
--- a/doc/classes/AudioEffectLowShelfFilter.xml
+++ b/doc/classes/AudioEffectLowShelfFilter.xml
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AudioEffectLowShelfFilter" inherits="AudioEffectFilter" version="4.0">
<brief_description>
+ Reduces all frequencies below the [member AudioEffectFilter.cutoff_hz].
</brief_description>
<description>
</description>
<tutorials>
+ <link title="Audio buses">https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AudioEffectRecord.xml b/doc/classes/AudioEffectRecord.xml
index a217342d98..6617d16290 100644
--- a/doc/classes/AudioEffectRecord.xml
+++ b/doc/classes/AudioEffectRecord.xml
@@ -7,7 +7,7 @@
Allows the user to record sound from a microphone. It sets and gets the format in which the audio file will be recorded (8-bit, 16-bit, or compressed). It checks whether or not the recording is active, and if it is, records the sound. It then returns the recorded sample.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/recording_with_microphone.html</link>
+ <link title="Recording with microphone">https://docs.godotengine.org/en/latest/tutorials/audio/recording_with_microphone.html</link>
</tutorials>
<methods>
<method name="get_recording" qualifiers="const">
diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml
index 49c6f5bb34..d5fd5d8f00 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -7,7 +7,7 @@
[AudioServer] is a low-level server interface for audio access. It is in charge of creating sample data (playable audio) as well as its playback via a voice interface.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
+ <link title="Audio buses">https://docs.godotengine.org/en/latest/tutorials/audio/audio_buses.html</link>
</tutorials>
<methods>
<method name="add_bus">
diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml
index d5c8e42515..58768dc008 100644
--- a/doc/classes/AudioStream.xml
+++ b/doc/classes/AudioStream.xml
@@ -7,7 +7,7 @@
Base class for audio streams. Audio streams are used for sound effects and music playback, and support WAV (via [AudioStreamSample]) and OGG (via [AudioStreamOGGVorbis]) file formats.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
+ <link title="Audio streams">https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
</tutorials>
<methods>
<method name="get_length" qualifiers="const">
diff --git a/doc/classes/AudioStreamGenerator.xml b/doc/classes/AudioStreamGenerator.xml
index e93da411cd..51254f9305 100644
--- a/doc/classes/AudioStreamGenerator.xml
+++ b/doc/classes/AudioStreamGenerator.xml
@@ -5,7 +5,7 @@
<description>
</description>
<tutorials>
- <link>https://github.com/godotengine/godot-demo-projects/tree/master/audio/generator</link>
+ <link title="Audio generator demo project">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 e3e17b8a93..cd8e8735b6 100644
--- a/doc/classes/AudioStreamGeneratorPlayback.xml
+++ b/doc/classes/AudioStreamGeneratorPlayback.xml
@@ -5,7 +5,7 @@
<description>
</description>
<tutorials>
- <link>https://github.com/godotengine/godot-demo-projects/tree/master/audio/generator</link>
+ <link title="Audio generator demo project">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 dbc3d3e21b..86048ca8c1 100644
--- a/doc/classes/AudioStreamPlayer.xml
+++ b/doc/classes/AudioStreamPlayer.xml
@@ -7,7 +7,7 @@
Plays an audio stream non-positionally.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
+ <link title="Audio streams">https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
</tutorials>
<methods>
<method name="get_playback_position">
diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml
index 844e2316ba..d8b9385736 100644
--- a/doc/classes/AudioStreamPlayer2D.xml
+++ b/doc/classes/AudioStreamPlayer2D.xml
@@ -7,7 +7,7 @@
Plays audio that dampens with distance from screen center.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
+ <link title="Audio streams">https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
</tutorials>
<methods>
<method name="get_playback_position">
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index bd90e3bd1a..aadbc865bb 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -5,9 +5,10 @@
</brief_description>
<description>
Plays a sound effect with directed sound effects, dampens with distance if needed, generates effect of hearable position in space.
+ By default, audio is heard from the camera position. This can be changed by adding a [Listener3D] node to the scene and enabling it by calling [method Listener3D.make_current] on it.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
+ <link title="Audio streams">https://docs.godotengine.org/en/latest/tutorials/audio/audio_streams.html</link>
</tutorials>
<methods>
<method name="get_playback_position">
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 3812b45b13..bf4d9383ac 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -65,8 +65,8 @@
<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 [member toggle_mode] is active).
</member>
- <member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut">
- [ShortCut] associated to the button.
+ <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">
If [code]true[/code], the button will add information about its shortcut in the tooltip.
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 59d3dc3643..cc4568dda6 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -7,7 +7,7 @@
This provides a default material with a wide variety of rendering features and properties without the need to write shader code. See the tutorial below for details.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/spatial_material.html</link>
+ <link title="Spatial material">https://docs.godotengine.org/en/latest/tutorials/3d/spatial_material.html</link>
</tutorials>
<methods>
<method name="get_feature" qualifiers="const">
diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml
index 47433d7adc..c614a281ae 100644
--- a/doc/classes/Basis.xml
+++ b/doc/classes/Basis.xml
@@ -10,8 +10,8 @@
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html</link>
+ <link title="Matrices and transforms">https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
+ <link title="Using 3D transforms">https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html</link>
</tutorials>
<methods>
<method name="Basis">
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index de05cfcd13..e0ccda957f 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -6,7 +6,8 @@
<description>
Button is the standard themed button. It can contain text and an icon, and will display them according to the current [Theme].
[b]Example of creating a button and assigning an action when pressed by code:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _ready():
var button = Button.new()
button.text = "Click me"
@@ -15,8 +16,24 @@
func _button_pressed():
print("Hello world!")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ var button = new Button();
+ button.Text = "Click me";
+ button.Connect("pressed", this, nameof(ButtonPressed));
+ AddChild(button);
+ }
+
+ private void ButtonPressed()
+ {
+ GD.Print("Hello world!");
+ }
+ [/csharp]
+ [/codeblocks]
Buttons (like all Control nodes) can also be created in the editor, but some situations may require creating them from code.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml
index df3ef71a2a..7244da56ca 100644
--- a/doc/classes/CPUParticles2D.xml
+++ b/doc/classes/CPUParticles2D.xml
@@ -8,7 +8,7 @@
See also [GPUParticles2D], which provides the same functionality with hardware acceleration, but may not run on older devices.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/particle_systems_2d.html</link>
+ <link title="Particle systems (2D)">https://docs.godotengine.org/en/latest/tutorials/2d/particle_systems_2d.html</link>
</tutorials>
<methods>
<method name="convert_from_particles">
diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml
index 3cc74beb58..3bbee993ac 100644
--- a/doc/classes/Callable.xml
+++ b/doc/classes/Callable.xml
@@ -6,15 +6,32 @@
<description>
[Callable] is a first class object which can be held in variables and passed to functions. It represents a given method in an [Object], and is typically used for signal callbacks.
[b]Example:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
var callable = Callable(self, "print_args")
func print_args(arg1, arg2, arg3 = ""):
prints(arg1, arg2, arg3)
+
func test():
callable.call("hello", "world") # Prints "hello world".
callable.call(Vector2.UP, 42, callable) # Prints "(0, -1) 42 Node(Node.gd)::print_args".
callable.call("invalid") # Invalid call, should have at least 2 arguments.
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ Callable callable = new Callable(this, "print_args");
+ public void PrintArgs(object arg1, object arg2, object arg3 = "")
+ {
+ GD.PrintS(arg1, arg2, arg3);
+ }
+
+ public void Test()
+ {
+ callable.Call("hello", "world"); // Prints "hello world".
+ callable.Call(Vector2.Up, 42, callable); // Prints "(0, -1) 42 Node(Node.gd)::print_args".
+ callable.Call("invalid"); // Invalid call, should have at least 2 arguments.
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 899988022f..946c4f8988 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -12,8 +12,8 @@
[b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
+ <link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
+ <link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
</tutorials>
<methods>
<method name="_draw" qualifiers="virtual">
@@ -318,13 +318,22 @@
<description>
Draws [code]text[/code] using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width.
[b]Example using the default project font:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
# If using this method in a script that redraws constantly, move the
# `default_font` declaration to a member variable assigned in `_ready()`
# so the Control is only created once.
var default_font = Control.new().get_font("font")
draw_string(default_font, Vector2(64, 64), "Hello world")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // If using this method in a script that redraws constantly, move the
+ // `default_font` declaration to a member variable assigned in `_ready()`
+ // so the Control is only created once.
+ Font defaultFont = new Control().GetFont("font");
+ DrawString(defaultFont, new Vector2(64, 64), "Hello world");
+ [/csharp]
+ [/codeblocks]
See also [method Font.draw].
</description>
</method>
diff --git a/doc/classes/CanvasLayer.xml b/doc/classes/CanvasLayer.xml
index 8202a29d44..89cd28b617 100644
--- a/doc/classes/CanvasLayer.xml
+++ b/doc/classes/CanvasLayer.xml
@@ -7,8 +7,8 @@
Canvas drawing layer. [CanvasItem] nodes that are direct or indirect children of a [CanvasLayer] will be drawn in that layer. The layer is a numeric index that defines the draw order. The default 2D scene renders with index 0, so a [CanvasLayer] with index -1 will be drawn below, and one with index 1 will be drawn above. This is very useful for HUDs (in layer 1+ or above), or backgrounds (in layer -1 or below).
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/canvas_layers.html</link>
+ <link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
+ <link title="Canvas layers">https://docs.godotengine.org/en/latest/tutorials/2d/canvas_layers.html</link>
</tutorials>
<methods>
<method name="get_canvas" qualifiers="const">
diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml
index c16e448498..d1759adf30 100644
--- a/doc/classes/CharFXTransform.xml
+++ b/doc/classes/CharFXTransform.xml
@@ -7,8 +7,8 @@
By setting various properties on this object, you can control how individual characters will be displayed in a [RichTextEffect].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
- <link>https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
+ <link title="BBCode in RichTextLabel">https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
+ <link title="RichTextEffect test project (third-party)">https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
</tutorials>
<methods>
</methods>
@@ -18,11 +18,18 @@
</member>
<member name="character" type="int" setter="set_character" getter="get_character" default="0">
The Unicode codepoint the character will use. This only affects non-whitespace characters. [method @GDScript.ord] can be useful here. For example, the following will replace all characters with asterisks:
- [codeblock]
+ [codeblocks]
+ [gdscript]
# `char_fx` is the CharFXTransform parameter from `_process_custom_fx()`.
# See the RichTextEffect documentation for details.
char_fx.character = ord("*")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // `char_fx` is the CharFXTransform parameter from `_process_custom_fx()`.
+ // See the RichTextEffect documentation for details.
+ charFx.Character = char.GetNumericValue('*');
+ [/csharp]
+ [/codeblocks]
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )">
The color the character will be drawn with.
diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml
index 9c42091eb8..f912bb98c9 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A checkbox allows the user to make a binary choice (choosing only one of two possible options). It's similar to [CheckButton] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckBox when toggling it has [b]no[/b] immediate effect on something. For instance, it should be used when toggling it will only do something once a confirmation button is pressed.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml
index 514ff9a691..b4f91cf3a8 100644
--- a/doc/classes/CheckButton.xml
+++ b/doc/classes/CheckButton.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
CheckButton is a toggle button displayed as a check field. It's similar to [CheckBox] in functionality, but it has a different appearance. To follow established UX patterns, it's recommended to use CheckButton when toggling it has an [b]immediate[/b] effect on something. For instance, it should be used if toggling it enables/disables a setting without requiring the user to press a confirmation button.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ClippedCamera3D.xml b/doc/classes/ClippedCamera3D.xml
index 58ecec828d..de90247536 100644
--- a/doc/classes/ClippedCamera3D.xml
+++ b/doc/classes/ClippedCamera3D.xml
@@ -90,7 +90,7 @@
If [code]true[/code], the camera stops on contact with [PhysicsBody3D]s.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The camera's collision mask. Only objects in at least one collision layer matching the mask will be detected.
+ The camera's collision mask. Only objects in at least one collision layer matching the mask will be detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0">
The camera's collision margin. The camera can't get closer than this distance to a colliding object.
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
new file mode 100644
index 0000000000..f6bc9e2cca
--- /dev/null
+++ b/doc/classes/CodeEdit.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="CodeEdit" inherits="TextEdit" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="clear_bookmarked_lines">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="clear_breakpointed_lines">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="clear_executing_lines">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_bookmarked_lines" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_breakpointed_lines" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_executing_lines" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_line_bookmarked" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_line_breakpointed" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_line_executing" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_as_bookmarked">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="bookmarked" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_as_breakpoint">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="breakpointed" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_as_executing">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="executing" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="draw_bookmarks" type="bool" setter="set_draw_bookmarks_gutter" getter="is_drawing_bookmarks_gutter" default="false">
+ </member>
+ <member name="draw_breakpoints_gutter" type="bool" setter="set_draw_breakpoints_gutter" getter="is_drawing_breakpoints_gutter" default="false">
+ </member>
+ <member name="draw_executing_lines" type="bool" setter="set_draw_executing_lines_gutter" getter="is_drawing_executing_lines_gutter" default="false">
+ </member>
+ <member name="draw_fold_gutter" type="bool" setter="set_draw_fold_gutter" getter="is_drawing_fold_gutter" default="false">
+ </member>
+ <member name="draw_line_numbers" type="bool" setter="set_draw_line_numbers" getter="is_draw_line_numbers_enabled" default="false">
+ </member>
+ <member name="zero_pad_line_numbers" type="bool" setter="set_line_numbers_zero_padded" getter="is_line_numbers_zero_padded" default="false">
+ </member>
+ </members>
+ <signals>
+ <signal name="breakpoint_toggled">
+ <argument index="0" name="line" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+ <theme_items>
+ <theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )">
+ </theme_item>
+ <theme_item name="bookmark" type="Texture2D">
+ </theme_item>
+ <theme_item name="bookmark_color" type="Color" default="Color( 0.5, 0.64, 1, 0.8 )">
+ </theme_item>
+ <theme_item name="brace_mismatch_color" type="Color" default="Color( 1, 0.2, 0.2, 1 )">
+ </theme_item>
+ <theme_item name="breakpoint" type="Texture2D">
+ </theme_item>
+ <theme_item name="breakpoint_color" type="Color" default="Color( 0.9, 0.29, 0.3, 1 )">
+ </theme_item>
+ <theme_item name="can_fold" type="Texture2D">
+ </theme_item>
+ <theme_item name="caret_background_color" type="Color" default="Color( 0, 0, 0, 1 )">
+ </theme_item>
+ <theme_item name="caret_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ </theme_item>
+ <theme_item name="code_folding_color" type="Color" default="Color( 0.8, 0.8, 0.8, 0.8 )">
+ </theme_item>
+ <theme_item name="completion" type="StyleBox">
+ </theme_item>
+ <theme_item name="completion_background_color" type="Color" default="Color( 0.17, 0.16, 0.2, 1 )">
+ </theme_item>
+ <theme_item name="completion_existing_color" type="Color" default="Color( 0.87, 0.87, 0.87, 0.13 )">
+ </theme_item>
+ <theme_item name="completion_font_color" type="Color" default="Color( 0.67, 0.67, 0.67, 1 )">
+ </theme_item>
+ <theme_item name="completion_lines" type="int" default="7">
+ </theme_item>
+ <theme_item name="completion_max_width" type="int" default="50">
+ </theme_item>
+ <theme_item name="completion_scroll_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </theme_item>
+ <theme_item name="completion_scroll_width" type="int" default="3">
+ </theme_item>
+ <theme_item name="completion_selected_color" type="Color" default="Color( 0.26, 0.26, 0.27, 1 )">
+ </theme_item>
+ <theme_item name="current_line_color" type="Color" default="Color( 0.25, 0.25, 0.26, 0.8 )">
+ </theme_item>
+ <theme_item name="executing_line" type="Texture2D">
+ </theme_item>
+ <theme_item name="executing_line_color" type="Color" default="Color( 0.98, 0.89, 0.27, 1 )">
+ </theme_item>
+ <theme_item name="focus" type="StyleBox">
+ </theme_item>
+ <theme_item name="folded" type="Texture2D">
+ </theme_item>
+ <theme_item name="font" type="Font">
+ </theme_item>
+ <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ </theme_item>
+ <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ </theme_item>
+ <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ </theme_item>
+ <theme_item name="line_number_color" type="Color" default="Color( 0.67, 0.67, 0.67, 0.4 )">
+ </theme_item>
+ <theme_item name="line_spacing" type="int" default="4">
+ </theme_item>
+ <theme_item name="mark_color" type="Color" default="Color( 1, 0.4, 0.4, 0.4 )">
+ </theme_item>
+ <theme_item name="normal" type="StyleBox">
+ </theme_item>
+ <theme_item name="read_only" type="StyleBox">
+ </theme_item>
+ <theme_item name="safe_line_number_color" type="Color" default="Color( 0.67, 0.78, 0.67, 0.6 )">
+ </theme_item>
+ <theme_item name="selection_color" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )">
+ </theme_item>
+ <theme_item name="space" type="Texture2D">
+ </theme_item>
+ <theme_item name="tab" type="Texture2D">
+ </theme_item>
+ <theme_item name="word_highlighted_color" type="Color" default="Color( 0.8, 0.9, 0.9, 0.15 )">
+ </theme_item>
+ </theme_items>
+</class>
diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml
index d2676e55d0..b4fcf9cd88 100644
--- a/doc/classes/CollisionShape2D.xml
+++ b/doc/classes/CollisionShape2D.xml
@@ -7,7 +7,7 @@
Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method CollisionObject2D.shape_owner_get_shape] to get the actual shape.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/CollisionShape3D.xml b/doc/classes/CollisionShape3D.xml
index 76515a65a7..177900dd4f 100644
--- a/doc/classes/CollisionShape3D.xml
+++ b/doc/classes/CollisionShape3D.xml
@@ -7,10 +7,10 @@
Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area3D] to give it a detection shape, or add it to a [PhysicsBody3D] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method CollisionObject3D.shape_owner_get_shape] to get the actual shape.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
- <method name="make_convex_from_brothers">
+ <method name="make_convex_from_siblings">
<return type="void">
</return>
<description>
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 240e70db9f..1d249a253c 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -8,6 +8,7 @@
You can also create a color from standardized color names by using [method @GDScript.ColorN] or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url].
If you want to supply values in a range of 0 to 255, you should use [method @GDScript.Color8].
[b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it's equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
+ [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url]
</description>
<tutorials>
</tutorials>
@@ -18,14 +19,40 @@
<argument index="0" name="from" type="String">
</argument>
<description>
- Constructs a color from an HTML hexadecimal color string in ARGB or RGB format. See also [method @GDScript.ColorN].
- [codeblock]
+ Constructs a color from an HTML hexadecimal color string in RGB or RGBA format. See also [method @GDScript.ColorN].
+ [codeblocks]
+ [gdscript]
# Each of the following creates the same color RGBA(178, 217, 10, 255).
- var c1 = Color("#ffb2d90a") # ARGB format with "#".
- var c2 = Color("ffb2d90a") # ARGB format.
var c3 = Color("#b2d90a") # RGB format with "#".
var c4 = Color("b2d90a") # RGB format.
- [/codeblock]
+ var c1 = Color("#b2d90aff") # RGBA format with "#".
+ var c2 = Color("b2d90aff") # RGBA format.
+ [/gdscript]
+ [csharp]
+ // Each of the following creates the same color RGBA(178, 217, 10, 255).
+ var c3 = new Color("#b2d90a");
+ var c4 = new Color("b2d90a"); // RGB format.
+ var c1 = new Color("#b2d90aff");
+ var c2 = new Color("b2d90aff"); // RGBA format.
+ [/csharp]
+ [/codeblocks]
+ You can also use the "web color" short-hand form by only using 3 or 4 digits.
+ [codeblocks]
+ [gdscript]
+ # Each of the following creates the same color RGBA(17, 34, 51, 255).
+ var c3 = Color("#123") # RGB format with "#".
+ var c4 = Color("123") # RGB format.
+ var c1 = Color("#123f") # RGBA format with "#".
+ var c2 = Color("123f") # RGBA format.
+ [/gdscript]
+ [csharp]
+ // Each of the following creates the same color RGBA(17, 34, 51, 255).
+ var c3 = new Color("#123");
+ var c4 = new Color("123"); // RGB format.
+ var c1 = new Color("#123f");
+ var c2 = new Color("123f"); // RGBA format.
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="Color">
@@ -35,9 +62,14 @@
</argument>
<description>
Constructs a color from a 32-bit integer (each byte represents a component of the RGBA profile).
- [codeblock]
+ [codeblocks]
+ [gdscript]
var c = Color(274) # Equivalent to RGBA(0, 0, 1, 18)
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var c = new Color(274); // Equivalent to RGBA(0, 0, 1, 18)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="Color">
@@ -49,9 +81,14 @@
</argument>
<description>
Constructs a color from an existing color, but with a custom alpha value.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var red = Color(Color.red, 0.5) # 50% transparent red.
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var red = new Color(Colors.Red, 0.5f); // 50% transparent red.
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="Color">
@@ -65,9 +102,14 @@
</argument>
<description>
Constructs a color from an RGB profile using values between 0 and 1. Alpha will always be 1.
- [codeblock]
- var c = Color(0.2, 1.0, 0.7) # Equivalent to RGBA(51, 255, 178, 255)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(0.2, 1.0, 0.7) # Equivalent to RGBA(51, 255, 178, 255)
+ [/gdscript]
+ [csharp]
+ var color = new Color(0.2f, 1.0f, 0.7f); // Equivalent to RGBA(51, 255, 178, 255)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="Color">
@@ -83,9 +125,14 @@
</argument>
<description>
Constructs a color from an RGBA profile using values between 0 and 1.
- [codeblock]
- var c = Color(0.2, 1.0, 0.7, 0.8) # Equivalent to RGBA(51, 255, 178, 204)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(0.2, 1.0, 0.7, 0.8) # Equivalent to RGBA(51, 255, 178, 204)
+ [/gdscript]
+ [csharp]
+ var color = new Color(0.2f, 1.0f, 0.7f, 0.8f); // Equivalent to RGBA(51, 255, 178, 255, 204)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="blend">
@@ -95,11 +142,18 @@
</argument>
<description>
Returns a new color resulting from blending this color over another. If the color is opaque, the result is also opaque. The second color may have a range of alpha values.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var bg = Color(0.0, 1.0, 0.0, 0.5) # Green with alpha of 50%
var fg = Color(1.0, 0.0, 0.0, 0.5) # Red with alpha of 50%
var blended_color = bg.blend(fg) # Brown with alpha of 75%
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var bg = new Color(0.0f, 1.0f, 0.0f, 0.5f); // Green with alpha of 50%
+ var fg = new Color(1.0f, 0.0f, 0.0f, 0.5f); // Red with alpha of 50%
+ Color blendedColor = bg.Blend(fg); // Brown with alpha of 75%
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="contrasted">
@@ -107,10 +161,16 @@
</return>
<description>
Returns the most contrasting color.
- [codeblock]
- var c = Color(0.3, 0.4, 0.9)
- var contrasted_color = c.contrasted() # Equivalent to RGBA(204, 229, 102, 255)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(0.3, 0.4, 0.9)
+ var contrasted_color = color.contrasted() # Equivalent to RGBA(204, 229, 102, 255)
+ [/gdscript]
+ [csharp]
+ var color = new Color(0.3f, 0.4f, 0.9f);
+ Color contrastedColor = color.Contrasted(); // Equivalent to RGBA(204, 229, 102, 255)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="darkened">
@@ -120,10 +180,16 @@
</argument>
<description>
Returns a new color resulting from making this color darker by the specified percentage (ratio from 0 to 1).
- [codeblock]
+ [codeblocks]
+ [gdscript]
var green = Color(0.0, 1.0, 0.0)
var darkgreen = green.darkened(0.2) # 20% darker than regular green
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var green = new Color(0.0f, 1.0f, 0.0f);
+ Color darkgreen = green.Darkened(0.2f); // 20% darker than regular green
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="from_hsv">
@@ -139,9 +205,14 @@
</argument>
<description>
Constructs a color from an HSV profile. [code]h[/code], [code]s[/code], and [code]v[/code] are values between 0 and 1.
- [codeblock]
- var c = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8)
+ [/gdscript]
+ [csharp]
+ Color color = Color.FromHsv(0.58f, 0.5f, 0.79f, 0.8f); // Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="inverted">
@@ -149,10 +220,16 @@
</return>
<description>
Returns the inverted color [code](1 - r, 1 - g, 1 - b, a)[/code].
- [codeblock]
- var c = Color(0.3, 0.4, 0.9)
- var inverted_color = c.inverted() # A color of an RGBA(178, 153, 26, 255)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(0.3, 0.4, 0.9)
+ var inverted_color = color.inverted() # A color of an RGBA(178, 153, 26, 255)
+ [/gdscript]
+ [csharp]
+ var color = new Color(0.3f, 0.4f, 0.9f);
+ Color invertedColor = color.Inverted(); // A color of an RGBA(178, 153, 26, 255)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="is_equal_approx">
@@ -173,11 +250,18 @@
</argument>
<description>
Returns the linear interpolation with another color. The interpolation factor [code]t[/code] is between 0 and 1.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var c1 = Color(1.0, 0.0, 0.0)
var c2 = Color(0.0, 1.0, 0.0)
- var li_c = c1.lerp(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)
- [/codeblock]
+ var lerp_color = c1.lerp(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)
+ [/gdscript]
+ [csharp]
+ var c1 = new Color(1.0f, 0.0f, 0.0f);
+ var c2 = new Color(0.0f, 1.0f, 0.0f);
+ Color lerpColor = c1.Lerp(c2, 0.5f); // A color of an RGBA(128, 128, 0, 255)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="lightened">
@@ -187,10 +271,16 @@
</argument>
<description>
Returns a new color resulting from making this color lighter by the specified percentage (ratio from 0 to 1).
- [codeblock]
+ [codeblocks]
+ [gdscript]
var green = Color(0.0, 1.0, 0.0)
var lightgreen = green.lightened(0.2) # 20% lighter than regular green
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var green = new Color(0.0f, 1.0f, 0.0f);
+ Color lightgreen = green.Lightened(0.2f); // 20% lighter than regular green
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_abgr32">
@@ -198,10 +288,16 @@
</return>
<description>
Returns the color's 32-bit integer in ABGR format (each byte represents a component of the ABGR profile). ABGR is the reversed version of the default format.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_abgr32()) # Prints 4281565439
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_abgr32()) # Prints 4281565439
+ [/gdscript]
+ [csharp]
+ var color = new Color(1.0f, 0.5f, 0.2f);
+ GD.Print(color.ToAbgr32()); // Prints 4281565439
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_abgr64">
@@ -209,10 +305,16 @@
</return>
<description>
Returns the color's 64-bit integer in ABGR format (each word represents a component of the ABGR profile). ABGR is the reversed version of the default format.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_abgr64()) # Prints -225178692812801
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_abgr64()) # Prints -225178692812801
+ [/gdscript]
+ [csharp]
+ var color = new Color(1.0f, 0.5f, 0.2f);
+ GD.Print(color.ToAbgr64()); // Prints -225178692812801
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_argb32">
@@ -220,10 +322,16 @@
</return>
<description>
Returns the color's 32-bit integer in ARGB format (each byte represents a component of the ARGB profile). ARGB is more compatible with DirectX.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_argb32()) # Prints 4294934323
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_argb32()) # Prints 4294934323
+ [/gdscript]
+ [csharp]
+ var color = new Color(1.0f, 0.5f, 0.2f);
+ GD.Print(color.ToArgb32()); // Prints 4294934323
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_argb64">
@@ -231,10 +339,16 @@
</return>
<description>
Returns the color's 64-bit integer in ARGB format (each word represents a component of the ARGB profile). ARGB is more compatible with DirectX.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_argb64()) # Prints -2147470541
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_argb64()) # Prints -2147470541
+ [/gdscript]
+ [csharp]
+ var color = new Color(1.0f, 0.5f, 0.2f);
+ GD.Print(color.ToArgb64()); // Prints -2147470541
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_html">
@@ -243,13 +357,20 @@
<argument index="0" name="with_alpha" type="bool" default="true">
</argument>
<description>
- Returns the color's HTML hexadecimal color string in ARGB format (ex: [code]ff34f822[/code]).
- Setting [code]with_alpha[/code] to [code]false[/code] excludes alpha from the hexadecimal string.
- [codeblock]
- var c = Color(1, 1, 1, 0.5)
- var s1 = c.to_html() # Returns "7fffffff"
- var s2 = c.to_html(false) # Returns "ffffff"
- [/codeblock]
+ Returns the color's HTML hexadecimal color string in RGBA format (ex: [code]ff34f822[/code]).
+ Setting [code]with_alpha[/code] to [code]false[/code] excludes alpha from the hexadecimal string (and uses RGB instead of RGBA format).
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 1, 1, 0.5)
+ var with_alpha = color.to_html() # Returns "ffffff7f"
+ var without_alpha = color.to_html(false) # Returns "ffffff"
+ [/gdscript]
+ [csharp]
+ var color = new Color(1, 1, 1, 0.5f);
+ String withAlpha = color.ToHtml(); // Returns "ffffff7f"
+ String withoutAlpha = color.ToHtml(false); // Returns "ffffff"
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_rgba32">
@@ -257,10 +378,16 @@
</return>
<description>
Returns the color's 32-bit integer in RGBA format (each byte represents a component of the RGBA profile). RGBA is Godot's default format.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_rgba32()) # Prints 4286526463
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_rgba32()) # Prints 4286526463
+ [/gdscript]
+ [csharp]
+ var color = new Color(1, 0.5f, 0.2f);
+ GD.Print(color.ToRgba32()); // Prints 4286526463
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="to_rgba64">
@@ -268,10 +395,16 @@
</return>
<description>
Returns the color's 64-bit integer in RGBA format (each word represents a component of the RGBA profile). RGBA is Godot's default format.
- [codeblock]
- var c = Color(1, 0.5, 0.2)
- print(c.to_rgba64()) # Prints -140736629309441
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var color = Color(1, 0.5, 0.2)
+ print(color.to_rgba64()) # Prints -140736629309441
+ [/gdscript]
+ [csharp]
+ var color = new Color(1, 0.5f, 0.2f);
+ GD.Print(color.ToRgba64()); // Prints -140736629309441
+ [/csharp]
+ [/codeblocks]
</description>
</method>
</methods>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index 67f64c8a66..36f7880060 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Encapsulates a [ColorPicker] making it accessible by pressing a button. Pressing the button will toggle the [ColorPicker] visibility.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ColorRect.xml b/doc/classes/ColorRect.xml
index 92f42b6dd3..9bfcf5071d 100644
--- a/doc/classes/ColorRect.xml
+++ b/doc/classes/ColorRect.xml
@@ -13,9 +13,14 @@
<members>
<member name="color" type="Color" setter="set_frame_color" getter="get_frame_color" default="Color( 1, 1, 1, 1 )">
The fill color.
- [codeblock]
+ [codeblocks]
+ [gdscript]
$ColorRect.color = Color(1, 0, 0, 1) # Set ColorRect's color to red.
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ GetNode&lt;ColorRect&gt;("ColorRect").Color = new Color(1, 0, 0, 1); // Set ColorRect's color to red.
+ [/csharp]
+ [/codeblocks]
</member>
</members>
<constants>
diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml
index 522d484131..da17d993e3 100644
--- a/doc/classes/ConfigFile.xml
+++ b/doc/classes/ConfigFile.xml
@@ -13,7 +13,8 @@
[/codeblock]
The stored data can be saved to or parsed from a file, though ConfigFile objects can also be used directly without accessing the filesystem.
The following example shows how to parse an INI-style file from the system, read its contents and store new values in it:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var config = ConfigFile.new()
var err = config.load("user://settings.cfg")
if err == OK: # If not, something went wrong with the file loading
@@ -24,7 +25,24 @@
config.set_value("audio", "mute", false)
# Save the changes by overwriting the previous file
config.save("user://settings.cfg")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var config = new ConfigFile();
+ Error err = config.Load("user://settings.cfg");
+ if (err == Error.Ok) // If not, something went wrong with the file loading
+ {
+ // Look for the display/width pair, and default to 1024 if missing
+ int screenWidth = (int)config.GetValue("display", "width", 1024);
+ // Store a variable if and only if it hasn't been defined yet
+ if (!config.HasSectionKey("audio", "mute"))
+ {
+ config.SetValue("audio", "mute", false);
+ }
+ // Save the changes by overwriting the previous file
+ config.Save("user://settings.cfg");
+ }
+ [/csharp]
+ [/codeblocks]
Keep in mind that section and property names can't contain spaces. Anything after a space will be ignored on save and on load.
ConfigFiles can also contain manually written comment lines starting with a semicolon ([code];[/code]). Those lines will be ignored when parsing the file. Note that comments will be lost when saving the ConfigFile. This can still be useful for dedicated server configuration files, which are typically never overwritten without explicit user action.
</description>
diff --git a/doc/classes/ConfirmationDialog.xml b/doc/classes/ConfirmationDialog.xml
index 6d5871508b..a850afdd9f 100644
--- a/doc/classes/ConfirmationDialog.xml
+++ b/doc/classes/ConfirmationDialog.xml
@@ -6,9 +6,14 @@
<description>
Dialog for confirmation of actions. This dialog inherits from [AcceptDialog], but has by default an OK and Cancel button (in host OS order).
To get cancel action, you can use:
- [codeblock]
+ [codeblocks]
+ [gdscript]
get_cancel().connect("pressed", self, "cancelled")
- [/codeblock].
+ [/gdscript]
+ [csharp]
+ GetCancel().Connect("pressed", this, nameof(Cancelled));
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 1f495bf91a..bb00ac33bf 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -13,10 +13,11 @@
Only one [Control] node can be in keyboard focus. Only the node in focus will receive keyboard events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus.
Sets [member mouse_filter] to [constant MOUSE_FILTER_IGNORE] to tell a [Control] node to ignore mouse or touch events. You'll need it if you place an icon on top of a button.
[Theme] resources change the Control's appearance. If you change the [Theme] on a [Control] node, it affects all of its children. To override some of the theme's parameters, call one of the [code]add_theme_*_override[/code] methods, like [method add_theme_font_override]. You can override the theme with the inspector.
+ [b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/gui/index.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
+ <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/gui/index.html</link>
+ <link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
</tutorials>
<methods>
<method name="_clips_input" qualifiers="virtual">
@@ -43,12 +44,27 @@
<description>
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]
+ [codeblocks]
+ [gdscript]
func _gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.pressed:
print("I've been clicked D:")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _GuiInput(InputEvent @event)
+ {
+ if (@event is InputEventMouseButton)
+ {
+ var mb = @event as InputEventMouseButton;
+ if (mb.ButtonIndex == (int)ButtonList.Left &amp;&amp; mb.Pressed)
+ {
+ GD.Print("I've been clicked D:");
+ }
+ }
+ }
+ [/csharp]
+ [/codeblocks]
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];
@@ -67,19 +83,39 @@
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 [code]null[/code] 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]
+ [codeblocks]
+ [gdscript]
func _make_custom_tooltip(for_text):
var label = Label.new()
label.text = for_text
return label
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override Godot.Object _MakeCustomTooltip(String forText)
+ {
+ var label = new Label();
+ label.Text = forText;
+ return label;
+ }
+ [/csharp]
+ [/codeblocks]
Example of usage with custom scene instance:
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _make_custom_tooltip(for_text):
var tooltip = preload("SomeTooltipScene.tscn").instance()
tooltip.get_node("Label").text = for_text
return tooltip
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override Godot.Object _MakeCustomTooltip(String forText)
+ {
+ Node tooltip = ResourceLoader.Load&lt;PackedScene&gt;("SomeTooltipScene.tscn").Instance();
+ tooltip.GetNode&lt;Label&gt;("Label").Text = forText;
+ return tooltip;
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="accept_event">
@@ -97,7 +133,25 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
- 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.
+ Overrides the [Color] with given [code]name[/code] in the [member theme] resource the control uses.
+ [b]Note:[/b] Unlike other theme overrides, there is no way to undo a color override without manually assigning the previous color.
+ [b]Example of overriding a label's color and resetting it later:[/b]
+ [codeblocks]
+ [gdscript]
+ # Override the child node "MyLabel"'s font color to orange.
+ $MyLabel.add_theme_color_override("font_color", Color(1, 0.5, 0))
+ # Reset the color by creating a new node to get the default value:
+ var default_label_color = Label.new().get_theme_color("font_color")
+ $MyLabel.add_theme_color_override("font_color", default_label_color)
+ [/gdscript]
+ [csharp]
+ // Override the child node "MyLabel"'s font color to orange.
+ GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0));
+ // Reset the color by creating a new node to get the default value:
+ var defaultLabelColor = new Label().GetThemeColor("font_color");
+ GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", defaultLabelColor);
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="add_theme_constant_override">
@@ -108,7 +162,7 @@
<argument index="1" name="constant" type="int">
</argument>
<description>
- 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.
+ Overrides an integer constant with given [code]name[/code] in the [member theme] resource the control uses. If the [code]constant[/code] is [code]0[/code], the override is cleared and the constant from assigned [Theme] is used.
</description>
</method>
<method name="add_theme_font_override">
@@ -119,7 +173,7 @@
<argument index="1" name="font" type="Font">
</argument>
<description>
- 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.
+ Overrides the font with given [code]name[/code] in the [member theme] resource the control uses. If [code]font[/code] is [code]null[/code] or invalid, the override is cleared and the font from assigned [Theme] is used.
</description>
</method>
<method name="add_theme_icon_override">
@@ -130,7 +184,7 @@
<argument index="1" name="texture" type="Texture2D">
</argument>
<description>
- 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.
+ Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. If [code]icon[/code] is [code]null[/code] or invalid, the override is cleared and the icon from assigned [Theme] is used.
</description>
</method>
<method name="add_theme_shader_override">
@@ -141,7 +195,7 @@
<argument index="1" name="shader" type="Shader">
</argument>
<description>
- Overrides the [Shader] with given [code]name[/code] in the [member theme] resource the control uses. If [code]shader[/code] is empty or invalid, the override is cleared and the shader from assigned [Theme] is used.
+ Overrides the [Shader] with given [code]name[/code] in the [member theme] resource the control uses. If [code]shader[/code] is [code]null[/code] or invalid, the override is cleared and the shader from assigned [Theme] is used.
</description>
</method>
<method name="add_theme_stylebox_override">
@@ -153,6 +207,31 @@
</argument>
<description>
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.
+ [b]Example of modifying a property in a StyleBox by duplicating it:[/b]
+ [codeblocks]
+ [gdscript]
+ # The snippet below assumes the child node MyButton has a StyleBoxFlat assigned.
+ # Resources are shared across instances, so we need to duplicate it
+ # to avoid modifying the appearance of all other buttons.
+ var new_stylebox_normal = $MyButton.get_theme_stylebox("normal").duplicate()
+ new_stylebox_normal.border_width_top = 3
+ new_stylebox_normal.border_color = Color(0, 1, 0.5)
+ $MyButton.add_theme_stylebox_override("normal", new_stylebox_normal)
+ # Remove the stylebox override:
+ $MyButton.add_theme_stylebox_override("normal", null)
+ [/gdscript]
+ [csharp]
+ // The snippet below assumes the child node MyButton has a StyleBoxFlat assigned.
+ // Resources are shared across instances, so we need to duplicate it
+ // to avoid modifying the appearance of all other buttons.
+ StyleBoxFlat newStyleboxNormal = GetNode&lt;Button&gt;("MyButton").GetThemeStylebox("normal").Duplicate() as StyleBoxFlat;
+ newStyleboxNormal.BorderWidthTop = 3;
+ newStyleboxNormal.BorderColor = new Color(0, 1, 0.5f);
+ GetNode&lt;Button&gt;("MyButton").AddThemeStyleboxOverride("normal", newStyleboxNormal);
+ // Remove the stylebox override:
+ GetNode&lt;Button&gt;("MyButton").AddThemeStyleboxOverride("normal", null);
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="can_drop_data" qualifiers="virtual">
@@ -165,12 +244,22 @@
<description>
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]
+ [codeblocks]
+ [gdscript]
func can_drop_data(position, data):
# Check position if it is relevant to you
# Otherwise, just check data
return typeof(data) == TYPE_DICTIONARY and data.has("expected")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override bool CanDropData(Vector2 position, object data)
+ {
+ // Check position if it is relevant to you
+ // Otherwise, just check data
+ return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("expected");
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="drop_data" qualifiers="virtual">
@@ -182,13 +271,24 @@
</argument>
<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]
+ [codeblocks]
+ [gdscript]
func can_drop_data(position, data):
return typeof(data) == TYPE_DICTIONARY and data.has("color")
-
func drop_data(position, data):
- color = data["color"]
- [/codeblock]
+ var color = data["color"]
+ [/gdscript]
+ [csharp]
+ public override bool CanDropData(Vector2 position, object data)
+ {
+ return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("color");
+ }
+ public override void DropData(Vector2 position, object data)
+ {
+ Color color = (Color)(data as Godot.Collections.Dictionary)["color"];
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="force_drag">
@@ -243,12 +343,22 @@
<description>
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]
+ [codeblocks]
+ [gdscript]
func get_drag_data(position):
- var mydata = make_data()
- set_drag_preview(make_preview(mydata))
+ var mydata = make_data() # This is your custom method generating the drag data.
+ set_drag_preview(make_preview(mydata)) # This is your custom method generating the preview of the drag data.
return mydata
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override object GetDragData(Vector2 position)
+ {
+ object mydata = MakeData(); // This is your custom method generating the drag data.
+ SetDragPreview(MakePreview(mydata)); // This is your custom method generating the preview of the drag data.
+ return mydata;
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="get_end" qualifiers="const">
@@ -334,10 +444,18 @@
</argument>
<description>
Returns a color from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _ready():
modulate = get_theme_color("font_color", "Button") #get the color defined for button fonts
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ Modulate = GetThemeColor("font_color", "Button"); //get the color defined for button fonts
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="get_theme_constant" qualifiers="const">
@@ -398,10 +516,18 @@
</return>
<description>
Creates an [InputEventMouseButton] that attempts to click the control. If the event is received, the control acquires focus.
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _process(delta):
grab_click_focus() #when clicking another Control node, this node will be clicked instead
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Process(float delta)
+ {
+ GrabClickFocus(); //when clicking another Control node, this node will be clicked instead
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="grab_focus">
@@ -628,24 +754,61 @@
Forwarding can be implemented in the target control similar to the methods [method get_drag_data], [method can_drop_data], and [method drop_data] but with two differences:
1. The function name must be suffixed with [b]_fw[/b]
2. The function must take an extra argument that is the control doing the forwarding
- [codeblock]
+ [codeblocks]
+ [gdscript]
# ThisControl.gd
extends Control
+ export(Control) var target_control
+
func _ready():
set_drag_forwarding(target_control)
# TargetControl.gd
extends Control
+
func can_drop_data_fw(position, data, from_control):
return true
func drop_data_fw(position, data, from_control):
- my_handle_data(data)
+ my_handle_data(data) # Your handler method.
func get_drag_data_fw(position, from_control):
set_drag_preview(my_preview)
return my_data()
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // ThisControl.cs
+ public class ThisControl : Control
+ {
+ [Export]
+ public Control TargetControl { get; set; }
+ public override void _Ready()
+ {
+ SetDragForwarding(TargetControl);
+ }
+ }
+
+ // TargetControl.cs
+ public class TargetControl : Control
+ {
+ public void CanDropDataFw(Vector2 position, object data, Control fromControl)
+ {
+ return true;
+ }
+
+ public void DropDataFw(Vector2 position, object data, Control fromControl)
+ {
+ MyHandleData(data); // Your handler method.
+ }
+
+ public void GetDragDataFw(Vector2 position, Control fromControl)
+ {
+ SetDragPreview(MyPreview);
+ return MyData();
+ }
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="set_drag_preview">
@@ -655,7 +818,8 @@
</argument>
<description>
Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree.
- [codeblock]
+ [codeblocks]
+ [gdscript]
export (Color, RGBA) var color = Color(1, 0, 0, 1)
func get_drag_data(position):
@@ -665,7 +829,22 @@
cpb.rect_size = Vector2(50, 50)
set_drag_preview(cpb)
return color
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ [Export]
+ public Color Color = new Color(1, 0, 0, 1);
+
+ public override object GetDragData(Vector2 position)
+ {
+ // Use a control that is not in the tree
+ var cpb = new ColorPickerButton();
+ cpb.Color = Color;
+ cpb.RectSize = new Vector2(50, 50);
+ SetDragPreview(cpb);
+ return Color;
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="set_end">
diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml
index 4edb3eda0a..b3bbbae94f 100644
--- a/doc/classes/Crypto.xml
+++ b/doc/classes/Crypto.xml
@@ -6,13 +6,12 @@
<description>
The Crypto class allows you to access some more advanced cryptographic functionalities in Godot.
For now, this includes generating cryptographically secure random bytes, RSA keys and self-signed X509 certificates generation, asymmetric key encryption/decryption, and signing/verification.
- [codeblock]
+ [codeblocks]
+ [gdscript]
extends Node
-
var crypto = Crypto.new()
var key = CryptoKey.new()
var cert = X509Certificate.new()
-
func _ready():
# Generate new RSA key.
key = crypto.generate_rsa(4096)
@@ -33,7 +32,42 @@
# Checks
assert(verified)
assert(data.to_utf8() == decrypted)
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ using Godot;
+ using System;
+ using System.Diagnostics;
+
+ public class CryptoNode : Node
+ {
+ public Crypto Crypto = new Crypto();
+ public CryptoKey Key = new CryptoKey();
+ public X509Certificate Cert = new X509Certificate();
+ public override void _Ready()
+ {
+ // Generate new RSA key.
+ Key = Crypto.GenerateRsa(4096);
+ // Generate new self-signed certificate with the given key.
+ Cert = Crypto.GenerateSelfSignedCertificate(Key, "CN=mydomain.com,O=My Game Company,C=IT");
+ // Save key and certificate in the user folder.
+ Key.Save("user://generated.key");
+ Cert.Save("user://generated.crt");
+ // Encryption
+ string data = "Some data";
+ byte[] encrypted = Crypto.Encrypt(Key, data.ToUTF8());
+ // Decryption
+ byte[] decrypted = Crypto.Decrypt(Key, encrypted);
+ // Signing
+ byte[] signature = Crypto.Sign(HashingContext.HashType.Sha256, Data.SHA256Buffer(), Key);
+ // Verifying
+ bool verified = Crypto.Verify(HashingContext.HashType.Sha256, Data.SHA256Buffer(), signature, Key);
+ // Checks
+ Debug.Assert(verified);
+ Debug.Assert(data.ToUTF8() == decrypted);
+ }
+ }
+ [/csharp]
+ [/codeblocks]
[b]Note:[/b] Not available in HTML5 exports.
</description>
<tutorials>
@@ -95,13 +129,22 @@
<description>
Generates a self-signed [X509Certificate] from the given [CryptoKey] and [code]issuer_name[/code]. The certificate validity will be defined by [code]not_before[/code] and [code]not_after[/code] (first valid date and last valid date). The [code]issuer_name[/code] must contain at least "CN=" (common name, i.e. the domain name), "O=" (organization, i.e. your company name), "C=" (country, i.e. 2 lettered ISO-3166 code of the country the organization is based in).
A small example to generate an RSA key and a X509 self-signed certificate.
- [codeblock]
+ [codeblocks]
+ [gdscript]
var crypto = Crypto.new()
# Generate 4096 bits RSA key.
var key = crypto.generate_rsa(4096)
# Generate self-signed certificate using the given key.
var cert = crypto.generate_self_signed_certificate(key, "CN=example.com,O=A Game Company,C=IT")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var crypto = new Crypto();
+ // Generate 4096 bits RSA key.
+ CryptoKey key = crypto.GenerateRsa(4096);
+ // Generate self-signed certificate using the given key.
+ X509Certificate cert = crypto.GenerateSelfSignedCertificate(key, "CN=mydomain.com,O=My Game Company,C=IT");
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="sign">
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index 5413fa33c6..7123deb206 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -73,7 +73,7 @@
[/codeblock]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#dictionary</link>
+ <link title="GDScript basics: Dictionary">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#dictionary</link>
</tutorials>
<methods>
<method name="clear">
diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml
index fc7ce94a2b..afd85a9cb7 100644
--- a/doc/classes/DirectionalLight3D.xml
+++ b/doc/classes/DirectionalLight3D.xml
@@ -7,7 +7,7 @@
A directional light is a type of [Light3D] node that models an infinite number of parallel rays covering the entire scene. It is used for lights with strong intensity that are located far away from the scene to model sunlight or moonlight. The worldspace location of the DirectionalLight3D transform (origin) is ignored. Only the basis is used to determine light direction.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
+ <link title="Lights and shadows">https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml
index a86dbfedde..bcdadcd970 100644
--- a/doc/classes/Directory.xml
+++ b/doc/classes/Directory.xml
@@ -24,7 +24,7 @@
[/codeblock]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link>
+ <link title="File system">https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link>
</tutorials>
<methods>
<method name="change_dir">
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 814c232668..28194587ab 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -901,6 +901,30 @@
<description>
</description>
</method>
+ <method name="window_set_mouse_passthrough">
+ <return type="void">
+ </return>
+ <argument index="0" name="region" type="PackedVector2Array">
+ </argument>
+ <argument index="1" name="window_id" type="int" default="0">
+ </argument>
+ <description>
+ Sets a polygonal region of the window which accepts mouse events. Mouse events outside the region will be passed through.
+ Passing an empty array will disable passthrough support (all mouse events will be intercepted by the window, which is the default behavior).
+ [codeblock]
+ # Set region, using Path2D node.
+ DisplayServer.window_set_mouse_passthrough($Path2D.curve.get_baked_points())
+
+ # Set region, using Polygon2D node.
+ DisplayServer.window_set_mouse_passthrough($Polygon2D.polygon)
+
+ # Reset region to default.
+ DisplayServer.window_set_mouse_passthrough([])
+ [/codeblock]
+ [b]Note:[/b] On Windows, the portion of a window that lies outside the region is not drawn, while on Linux and macOS it is.
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows.
+ </description>
+ </method>
<method name="window_set_position">
<return type="void">
</return>
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index 5d8ae29175..b0635892be 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -4,7 +4,7 @@
DynamicFont renders vector font files at runtime.
</brief_description>
<description>
- DynamicFont renders vector font files (such as TTF or OTF) dynamically at runtime instead of using a prerendered texture atlas like [BitmapFont]. This trades the faster loading time of [BitmapFont]s for the ability to change font parameters like size and spacing during runtime. [DynamicFontData] is used for referencing the font file paths. DynamicFont also supports defining one or more fallbacks fonts, which will be used when displaying a character not supported by the main font.
+ DynamicFont renders vector font files (such as TTF or OTF) dynamically at runtime instead of using a prerendered texture atlas like [BitmapFont]. This trades the faster loading time of [BitmapFont]s for the ability to change font parameters like size and spacing during runtime. [DynamicFontData] is used for referencing the font file paths. DynamicFont also supports defining one or more fallback fonts, which will be used when displaying a character not supported by the main font.
DynamicFont uses the [url=https://www.freetype.org/]FreeType[/url] library for rasterization.
[codeblock]
var dynamic_font = DynamicFont.new()
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 6bcaabc39e..9ef2bd21cc 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -70,24 +70,24 @@
<description>
</description>
</method>
- <method name="add_ios_framework">
+ <method name="add_ios_embedded_framework">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
- Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project.
+ Adds a dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project and embeds it into resulting binary.
+ [b]Note:[/b] For static libraries (*.a) works in same way as [code]add_ios_framework[/code].
+ This method should not be used for System libraries as they are already present on the device.
</description>
</method>
- <method name="add_ios_embedded_framework">
+ <method name="add_ios_framework">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
- Adds a dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project and embeds it into resulting binary.
- [b]Note:[/b] For static libraries (*.a) works in same way as [code]add_ios_framework[/code].
- This method should not be used for System libraries as they are already present on the device.
+ Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project.
</description>
</method>
<method name="add_ios_linker_flags">
diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml
index eb03d3010f..e05a685dd7 100644
--- a/doc/classes/EditorFeatureProfile.xml
+++ b/doc/classes/EditorFeatureProfile.xml
@@ -135,15 +135,15 @@
<constant name="FEATURE_SCENE_TREE" value="3" enum="Feature">
Scene tree editing. If this feature is disabled, the Scene tree dock will still be visible but will be read-only.
</constant>
- <constant name="FEATURE_IMPORT_DOCK" value="4" enum="Feature">
- The Import dock. If this feature is disabled, the Import dock won't be visible.
- </constant>
- <constant name="FEATURE_NODE_DOCK" value="5" enum="Feature">
+ <constant name="FEATURE_NODE_DOCK" value="4" enum="Feature">
The Node dock. If this feature is disabled, signals and groups won't be visible and modifiable from the editor.
</constant>
- <constant name="FEATURE_FILESYSTEM_DOCK" value="6" enum="Feature">
+ <constant name="FEATURE_FILESYSTEM_DOCK" value="5" enum="Feature">
The FileSystem dock. If this feature is disabled, the FileSystem dock won't be visible.
</constant>
+ <constant name="FEATURE_IMPORT_DOCK" value="6" enum="Feature">
+ The Import dock. If this feature is disabled, the Import dock won't be visible.
+ </constant>
<constant name="FEATURE_MAX" value="7" enum="Feature">
Represents the size of the [enum Feature] enum.
</constant>
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index ea2dfae9a5..b290557336 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -49,7 +49,7 @@
[/codeblock]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/editor/import_plugins.html</link>
+ <link title="Import plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/import_plugins.html</link>
</tutorials>
<methods>
<method name="get_import_options" qualifiers="virtual">
diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml
index b81281b5b6..8865939eb1 100644
--- a/doc/classes/EditorNode3DGizmoPlugin.xml
+++ b/doc/classes/EditorNode3DGizmoPlugin.xml
@@ -7,7 +7,7 @@
EditorNode3DGizmoPlugin allows you to define a new type of Gizmo. There are two main ways to do so: extending [EditorNode3DGizmoPlugin] for the simpler gizmos, or creating a new [EditorNode3DGizmo] type. See the tutorial in the documentation for more info.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/editor/spatial_gizmos.html</link>
+ <link title="Spatial gizmo plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/spatial_gizmos.html</link>
</tutorials>
<methods>
<method name="add_material">
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 36076d8909..6a64a7aa55 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -7,7 +7,7 @@
Plugins are used by the editor to extend functionality. The most common types of plugins are those which edit a given node or resource type, import plugins and export plugins. See also [EditorScript] to add functions to the editor.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/editor/index.html</link>
+ <link title="Editor plugins tutorial index">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/index.html</link>
</tutorials>
<methods>
<method name="add_autoload_singleton">
diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml
index 56fc0e3d1a..cb1f5d2e77 100644
--- a/doc/classes/EditorScenePostImport.xml
+++ b/doc/classes/EditorScenePostImport.xml
@@ -26,7 +26,7 @@
[/codeblock]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_scenes.html#custom-script</link>
+ <link title="Importing 3D scenes: Custom script">https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_scenes.html#custom-script</link>
</tutorials>
<methods>
<method name="get_source_file" qualifiers="const">
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index bbab0bf8cf..caee6a0c07 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -11,8 +11,8 @@
- Adjustments
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/environment_and_post_processing.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/high_dynamic_range.html</link>
+ <link title="Environment and post-processing">https://docs.godotengine.org/en/latest/tutorials/3d/environment_and_post_processing.html</link>
+ <link title="Light transport in game engines">https://docs.godotengine.org/en/latest/tutorials/3d/high_dynamic_range.html</link>
</tutorials>
<methods>
<method name="is_glow_level_enabled" qualifiers="const">
@@ -95,47 +95,20 @@
<member name="background_mode" type="int" setter="set_background" getter="get_background" enum="Environment.BGMode" default="0">
The background mode. See [enum BGMode] for possible values.
</member>
- <member name="fog_color" type="Color" setter="set_fog_color" getter="get_fog_color" default="Color( 0.5, 0.6, 0.7, 1 )">
- The fog's [Color].
- </member>
- <member name="fog_depth_begin" type="float" setter="set_fog_depth_begin" getter="get_fog_depth_begin" default="10.0">
- The fog's depth starting distance from the camera.
- </member>
- <member name="fog_depth_curve" type="float" setter="set_fog_depth_curve" getter="get_fog_depth_curve" default="1.0">
- The fog depth's intensity curve. A number of presets are available in the [b]Inspector[/b] by right-clicking the curve.
- </member>
- <member name="fog_depth_enabled" type="bool" setter="set_fog_depth_enabled" getter="is_fog_depth_enabled" default="true">
- If [code]true[/code], the depth fog effect is enabled. When enabled, fog will appear in the distance (relative to the camera).
- </member>
- <member name="fog_depth_end" type="float" setter="set_fog_depth_end" getter="get_fog_depth_end" default="100.0">
- The 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 Camera3D.far] value.
+ <member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.001">
</member>
<member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" default="false">
- If [code]true[/code], fog effects are enabled. [member fog_height_enabled] and/or [member fog_depth_enabled] must be set to [code]true[/code] 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">
- The height fog's intensity. A number of presets are available in the [b]Inspector[/b] by right-clicking the curve.
+ If [code]true[/code], fog effects are enabled.
</member>
- <member name="fog_height_enabled" type="bool" setter="set_fog_height_enabled" getter="is_fog_height_enabled" default="false">
- If [code]true[/code], the height fog effect is enabled. When enabled, fog will appear in a defined height range, regardless of the distance from the camera. This can be used to simulate "deep water" effects with a lower performance cost compared to a dedicated shader.
+ <member name="fog_height" type="float" setter="set_fog_height" getter="get_fog_height" default="0.0">
</member>
- <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 name="fog_height_density" type="float" setter="set_fog_height_density" getter="get_fog_height_density" default="0.0">
</member>
- <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 name="fog_light_color" type="Color" setter="set_fog_light_color" getter="get_fog_light_color" default="Color( 0.5, 0.6, 0.7, 1 )">
</member>
- <member name="fog_sun_amount" type="float" setter="set_fog_sun_amount" getter="get_fog_sun_amount" default="0.0">
- The intensity of the depth fog color transition when looking towards the sun. The sun's direction is determined automatically using the DirectionalLight3D node in the scene.
+ <member name="fog_light_energy" type="float" setter="set_fog_light_energy" getter="get_fog_light_energy" default="1.0">
</member>
- <member name="fog_sun_color" type="Color" setter="set_fog_sun_color" getter="get_fog_sun_color" default="Color( 1, 0.9, 0.7, 1 )">
- The depth fog's [Color] when looking towards the sun.
- </member>
- <member name="fog_transmit_curve" type="float" setter="set_fog_transmit_curve" getter="get_fog_transmit_curve" default="1.0">
- The intensity of the fog light transmittance effect. Amount of light that the fog transmits.
- </member>
- <member name="fog_transmit_enabled" type="bool" setter="set_fog_transmit_enabled" getter="is_fog_transmit_enabled" default="false">
- Enables fog's light transmission effect. If [code]true[/code], light will be more visible in the fog to simulate light scattering as in real life.
+ <member name="fog_sun_scatter" type="float" setter="set_fog_sun_scatter" getter="get_fog_sun_scatter" default="0.0">
</member>
<member name="glow_blend_mode" type="int" setter="set_glow_blend_mode" getter="get_glow_blend_mode" enum="Environment.GlowBlendMode" default="2">
The glow blending mode.
@@ -265,6 +238,22 @@
<member name="tonemap_white" type="float" setter="set_tonemap_white" getter="get_tonemap_white" default="1.0">
The white reference value for tonemapping. Only effective if the [member tonemap_mode] isn't set to [constant TONE_MAPPER_LINEAR].
</member>
+ <member name="volumetric_fog_density" type="float" setter="set_volumetric_fog_density" getter="get_volumetric_fog_density" default="0.01">
+ </member>
+ <member name="volumetric_fog_detail_spread" type="float" setter="set_volumetric_fog_detail_spread" getter="get_volumetric_fog_detail_spread" default="2.0">
+ </member>
+ <member name="volumetric_fog_enabled" type="bool" setter="set_volumetric_fog_enabled" getter="is_volumetric_fog_enabled" default="false">
+ </member>
+ <member name="volumetric_fog_gi_inject" type="float" setter="set_volumetric_fog_gi_inject" getter="get_volumetric_fog_gi_inject" default="0.0">
+ </member>
+ <member name="volumetric_fog_length" type="float" setter="set_volumetric_fog_length" getter="get_volumetric_fog_length" default="64.0">
+ </member>
+ <member name="volumetric_fog_light" type="Color" setter="set_volumetric_fog_light" getter="get_volumetric_fog_light" default="Color( 0, 0, 0, 1 )">
+ </member>
+ <member name="volumetric_fog_light_energy" type="float" setter="set_volumetric_fog_light_energy" getter="get_volumetric_fog_light_energy" default="1.0">
+ </member>
+ <member name="volumetric_fog_shadow_filter" type="int" setter="set_volumetric_fog_shadow_filter" getter="get_volumetric_fog_shadow_filter" enum="Environment.VolumetricFogShadowFilter" default="1">
+ </member>
</members>
<constants>
<constant name="BG_CLEAR_COLOR" value="0" enum="BGMode">
@@ -360,5 +349,13 @@
</constant>
<constant name="SDFGI_Y_SCALE_50_PERCENT" value="2" enum="SDFGIYScale">
</constant>
+ <constant name="VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED" value="0" enum="VolumetricFogShadowFilter">
+ </constant>
+ <constant name="VOLUMETRIC_FOG_SHADOW_FILTER_LOW" value="1" enum="VolumetricFogShadowFilter">
+ </constant>
+ <constant name="VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM" value="2" enum="VolumetricFogShadowFilter">
+ </constant>
+ <constant name="VOLUMETRIC_FOG_SHADOW_FILTER_HIGH" value="3" enum="VolumetricFogShadowFilter">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml
index fcd1aa43c0..f2611dc850 100644
--- a/doc/classes/Expression.xml
+++ b/doc/classes/Expression.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
An expression can be made of any arithmetic operation, built-in math function call, method call of a passed instance, or built-in type construction call.
- An example expression text using the built-in math functions could be [code]sqrt(pow(3,2) + pow(4,2))[/code].
+ An example expression text using the built-in math functions could be [code]sqrt(pow(3, 2) + pow(4, 2))[/code].
In the following example we use a [LineEdit] node to write our expression and show the result.
[codeblock]
onready var expression = Expression.new()
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index d91203d91f..f1b9106d35 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -21,9 +21,10 @@
return content
[/codeblock]
In the example above, the file will be saved in the user data folder as specified in the [url=https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html]Data paths[/url] documentation.
+ [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of the [File] API, as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link>
+ <link title="File system">https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link>
</tutorials>
<methods>
<method name="close">
@@ -48,7 +49,7 @@
</argument>
<description>
Returns [code]true[/code] if the file exists in the given path.
- [b]Note:[/b] Many resources types are imported (e.g. textures or sound files), and that their source asset will not be included in the exported game, as only the imported version is used (in the [code]res://.import[/code] folder). To check for the existence of such resources while taking into account the remapping to their imported location, use [method ResourceLoader.exists]. Typically, using [code]File.file_exists[/code] on an imported resource would work while you are developing in the editor (the source asset is present in [code]res://[/code], but fail when exported).
+ [b]Note:[/b] Many resources types are imported (e.g. textures or sound files), and their source asset will not be included in the exported game, as only the imported version is used. See [method ResourceLoader.exists] for an alternative approach that takes resource remapping into account.
</description>
</method>
<method name="get_16" qualifiers="const">
@@ -451,16 +452,16 @@
</members>
<constants>
<constant name="READ" value="1" enum="ModeFlags">
- Opens the file for read operations.
+ Opens the file for read operations. The cursor is positioned at the beginning of the file.
</constant>
<constant name="WRITE" value="2" enum="ModeFlags">
- Opens the file for write operations. Create it if the file does not exist and truncate if it exists.
+ Opens the file for write operations. The file is created if it does not exist, and truncated if it does.
</constant>
<constant name="READ_WRITE" value="3" enum="ModeFlags">
- Opens the file for read and write operations. Does not truncate the file.
+ Opens the file for read and write operations. Does not truncate the file. The cursor is positioned at the beginning of the file.
</constant>
<constant name="WRITE_READ" value="7" enum="ModeFlags">
- Opens the file for read and write operations. Create it if the file does not exist and truncate if it exists.
+ Opens the file for read and write operations. The file is created if it does not exist, and truncated if it does. The cursor is positioned at the beginning of the file.
</constant>
<constant name="COMPRESSION_FASTLZ" value="0" enum="CompressionMode">
Uses the [url=http://fastlz.org/]FastLZ[/url] compression method.
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index eaaccbd0dd..b4afee7610 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -57,6 +57,7 @@
<members>
<member name="access" type="int" setter="set_access" getter="get_access" enum="FileDialog.Access" default="0">
The file system access scope. See enum [code]Access[/code] constants.
+ [b]Warning:[/b] Currently, in sandboxed environments such as HTML5 builds or sandboxed macOS apps, FileDialog cannot access the host file system. See [url=https://github.com/godotengine/godot-proposals/issues/1123]godot-proposals#1123[/url].
</member>
<member name="current_dir" type="String" setter="set_current_dir" getter="get_current_dir" default="&quot;res://&quot;">
The current working directory of the file dialog.
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index ce6a25e191..f49fbf0d2a 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -5,6 +5,8 @@
</brief_description>
<description>
Font contains a Unicode-compatible character set, as well as the ability to draw it with variable width, ascent, descent and kerning. For creating fonts from TTF files (or other font formats), see the editor support for fonts.
+ [b]Note:[/b] If a DynamicFont doesn't contain a character used in a string, the character in question will be replaced with codepoint [code]0xfffd[/code] if it's available in the DynamicFont. If this replacement character isn't available in the DynamicFont, the character will be hidden without displaying any replacement character in the string.
+ [b]Note:[/b] If a BitmapFont doesn't contain a character used in a string, the character in question will be hidden without displaying any replacement character in the string.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml
index 8885f360a3..9199468ab3 100644
--- a/doc/classes/GIProbe.xml
+++ b/doc/classes/GIProbe.xml
@@ -8,7 +8,7 @@
Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/quality/gi_probes/quality].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link>
+ <link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link>
</tutorials>
<methods>
<method name="bake">
diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml
index ee67b5052c..244bdcf2f3 100644
--- a/doc/classes/GPUParticles2D.xml
+++ b/doc/classes/GPUParticles2D.xml
@@ -8,7 +8,7 @@
Use the [code]process_material[/code] property to add a [ParticlesMaterial] to configure particle appearance and behavior. Alternatively, you can add a [ShaderMaterial] which will be applied to all particles.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/particle_systems_2d.html</link>
+ <link title="Particle systems (2D)">https://docs.godotengine.org/en/latest/tutorials/2d/particle_systems_2d.html</link>
</tutorials>
<methods>
<method name="capture_rect" qualifiers="const">
@@ -33,7 +33,7 @@
<member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="GPUParticles2D.DrawOrder" default="0">
Particle draw order. Uses [enum DrawOrder] values.
</member>
- <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" default="false">
+ <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" default="true">
If [code]true[/code], particles are being emitted.
</member>
<member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio" default="0.0">
diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml
index add8f28bf8..8444610f49 100644
--- a/doc/classes/GPUParticles3D.xml
+++ b/doc/classes/GPUParticles3D.xml
@@ -8,7 +8,7 @@
Use the [code]process_material[/code] property to add a [ParticlesMaterial] to configure particle appearance and behavior. Alternatively, you can add a [ShaderMaterial] which will be applied to all particles.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/controlling_thousands_of_fish.html</link>
+ <link title="Controlling thousands of fish with Particles">https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/controlling_thousands_of_fish.html</link>
</tutorials>
<methods>
<method name="capture_aabb" qualifiers="const">
@@ -18,6 +18,22 @@
Returns the axis-aligned bounding box that contains all the particles that are active in the current frame.
</description>
</method>
+ <method name="emit_particle">
+ <return type="void">
+ </return>
+ <argument index="0" name="xform" type="Transform">
+ </argument>
+ <argument index="1" name="velocity" type="Vector3">
+ </argument>
+ <argument index="2" name="color" type="Color">
+ </argument>
+ <argument index="3" name="custom" type="Color">
+ </argument>
+ <argument index="4" name="flags" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_draw_pass_mesh" qualifiers="const">
<return type="Mesh">
</return>
@@ -68,7 +84,7 @@
<member name="draw_passes" type="int" setter="set_draw_passes" getter="get_draw_passes" default="1">
The number of draw passes when rendering particles.
</member>
- <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" default="false">
+ <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" default="true">
If [code]true[/code], particles are being emitted.
</member>
<member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio" default="0.0">
@@ -101,6 +117,8 @@
<member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0">
Speed scaling ratio. A value of [code]0[/code] can be used to pause the particles.
</member>
+ <member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath(&quot;&quot;)">
+ </member>
<member name="visibility_aabb" type="AABB" setter="set_visibility_aabb" getter="get_visibility_aabb" default="AABB( -4, -4, -4, 8, 8, 8 )">
The [AABB] that determines the area of the world part of which needs to be visible on screen for the particle system to be active.
</member>
@@ -115,6 +133,16 @@
<constant name="DRAW_ORDER_VIEW_DEPTH" value="2" enum="DrawOrder">
Particles are drawn in order of depth.
</constant>
+ <constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags">
+ </constant>
+ <constant name="EMIT_FLAG_ROTATION_SCALE" value="2" enum="EmitFlags">
+ </constant>
+ <constant name="EMIT_FLAG_VELOCITY" value="4" enum="EmitFlags">
+ </constant>
+ <constant name="EMIT_FLAG_COLOR" value="8" enum="EmitFlags">
+ </constant>
+ <constant name="EMIT_FLAG_CUSTOM" value="16" enum="EmitFlags">
+ </constant>
<constant name="MAX_DRAW_PASSES" value="4">
Maximum number of draw passes supported.
</constant>
diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml
index e13dc43104..6ee794c5c4 100644
--- a/doc/classes/GridContainer.xml
+++ b/doc/classes/GridContainer.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GridContainer" inherits="Container" version="4.0">
<brief_description>
- Grid container used to arrange elements in a grid like layout.
+ Grid container used to arrange Control-derived children in a grid like layout.
</brief_description>
<description>
- Grid container will arrange its children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns. For example, if the container has 5 children, and 2 columns, there will be 3 rows in the container.
+ GridContainer will arrange its Control-derived children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns. For example, if the container has 5 children, and 2 columns, there will be 3 rows in the container.
Notice that grid layout will preserve the columns and rows for every size of the container, and that empty columns will be expanded automatically.
+ [b]Note:[/b] GridContainer only works with child nodes inheriting from Control. It won't rearrange child nodes inheriting from Node2D.
</description>
<tutorials>
</tutorials>
@@ -13,7 +14,7 @@
</methods>
<members>
<member name="columns" type="int" setter="set_columns" getter="get_columns" default="1">
- The number of columns in the [GridContainer]. If modified, [GridContainer] reorders its children to accommodate the new layout.
+ The number of columns in the [GridContainer]. If modified, [GridContainer] reorders its Control-derived children to accommodate the new layout.
</member>
</members>
<constants>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index 7e8f0807ac..9dc38b018a 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HTTPClient" inherits="Reference" version="4.0">
<brief_description>
- Hyper-text transfer protocol client.
+ Low-level hyper-text transfer protocol client.
</brief_description>
<description>
- Hyper-text transfer protocol client (sometimes called "User Agent"). Used to make HTTP requests to download web content, upload files and other data or to communicate with various services, among other use cases. See [HTTPRequest] for an higher-level alternative.
+ Hyper-text transfer protocol client (sometimes called "User Agent"). Used to make HTTP requests to download web content, upload files and other data or to communicate with various services, among other use cases. [b]See the [HTTPRequest] node for an higher-level alternative.[/b]
[b]Note:[/b] This client only needs to connect to a host once (see [method connect_to_host]) to send multiple requests. Because of this, methods that take URLs usually take just the part after the host instead of the full URL, as the client is already connected to a host. See [method request] for a full example and to get started.
A [HTTPClient] should be reused between multiple requests or to connect to different hosts instead of creating one client per request. Supports SSL and SSL server certificate verification. HTTP status codes in the 2xx range indicate success, 3xx redirection (i.e. "try again, but over here"), 4xx something was wrong with the request, and 5xx something went wrong on the server's side.
For more information on HTTP, see https://developer.mozilla.org/en-US/docs/Web/HTTP (or read RFC 2616 to get it straight from the source: https://tools.ietf.org/html/rfc2616).
[b]Note:[/b] When performing HTTP requests from a project exported to HTML5, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/http_client_class.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
+ <link title="HTTP client class">https://docs.godotengine.org/en/latest/tutorials/networking/http_client_class.html</link>
+ <link title="SSL certificates">https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
</tutorials>
<methods>
<method name="close">
@@ -152,6 +152,7 @@
var headers = ["Content-Type: application/x-www-form-urlencoded", "Content-Length: " + str(query_string.length())]
var result = http_client.request(http_client.METHOD_POST, "index.php", headers, query_string)
[/codeblock]
+ [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example.
</description>
</method>
<method name="request_raw">
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 61e0d2e2b9..8cc7ecfbe3 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -64,11 +64,16 @@
add_child(texture_rect)
texture_rect.texture = texture
[/codeblock]
+
+ [b]Gzipped response bodies[/b]
+ HttpRequest will automatically handle decompression of response bodies.
+ A "Accept-Encoding" header will be automatically added to each of your requests, unless one is already specified.
+ Any response with a "Content-Encoding: gzip" header will automatically be decompressed and delivered to you as a uncompressed bytes.
[b]Note:[/b] When performing HTTP requests from a project exported to HTML5, keep in mind the remote server may not allow requests from foreign origins due to [url=https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS]CORS[/url]. If you host the server in question, you should modify its backend to allow requests from foreign origins by adding the [code]Access-Control-Allow-Origin: *[/code] HTTP header.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/http_request_class.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
+ <link title="Making HTTP requests">https://docs.godotengine.org/en/latest/tutorials/networking/http_request_class.html</link>
+ <link title="SSL certificates">https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
</tutorials>
<methods>
<method name="cancel_request">
@@ -116,12 +121,37 @@
<description>
Creates request on the underlying [HTTPClient]. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request].
Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host.
+ [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example.
+ </description>
+ </method>
+ <method name="request_raw">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="url" type="String">
+ </argument>
+ <argument index="1" name="custom_headers" type="PackedStringArray" default="PackedStringArray( )">
+ </argument>
+ <argument index="2" name="ssl_validate_domain" type="bool" default="true">
+ </argument>
+ <argument index="3" name="method" type="int" enum="HTTPClient.Method" default="0">
+ </argument>
+ <argument index="4" name="request_data_raw" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ Creates request on the underlying [HTTPClient] using a raw array of bytes for the request body. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request].
+ Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host.
</description>
</method>
</methods>
<members>
+ <member name="accept_gzip" type="bool" setter="set_accept_gzip" getter="is_accepting_gzip" default="true">
+ If [code]true[/code], this header will be added to each request: [code]Accept-Encoding: gzip, deflate[/code] telling servers that it's okay to compress response bodies.
+ Any Response body declaring a [code]Content-Encoding[/code] of either [code]gzip[/code] or [code]deflate[/code] will then be automatically decompressed, and the uncompressed bytes will be delivered via [code]request_completed[/code].
+ If the user has specified their own [code]Accept-Encoding[/code] header, then no header will be added regaurdless of [code]accept_gzip[/code].
+ If [code]false[/code] no header will be added, and no decompression will be performed on response bodies. The raw bytes of the response body will be returned via [code]request_completed[/code].
+ </member>
<member name="body_size_limit" type="int" setter="set_body_size_limit" getter="get_body_size_limit" default="-1">
- Maximum allowed size for response bodies.
+ Maximum allowed size for response bodies. If the response body is compressed, this will be used as the maximum allowed size for the decompressed body.
</member>
<member name="download_chunk_size" type="int" setter="set_download_chunk_size" getter="get_download_chunk_size" default="4096">
The size of the buffer used and maximum bytes to read per iteration. See [member HTTPClient.read_chunk_size].
@@ -178,19 +208,21 @@
<constant name="RESULT_BODY_SIZE_LIMIT_EXCEEDED" value="7" enum="Result">
Request exceeded its maximum size limit, see [member body_size_limit].
</constant>
- <constant name="RESULT_REQUEST_FAILED" value="8" enum="Result">
+ <constant name="RESULT_BODY_DECOMPRESS_FAILED" value="8" enum="Result">
+ </constant>
+ <constant name="RESULT_REQUEST_FAILED" value="9" enum="Result">
Request failed (currently unused).
</constant>
- <constant name="RESULT_DOWNLOAD_FILE_CANT_OPEN" value="9" enum="Result">
+ <constant name="RESULT_DOWNLOAD_FILE_CANT_OPEN" value="10" enum="Result">
HTTPRequest couldn't open the download file.
</constant>
- <constant name="RESULT_DOWNLOAD_FILE_WRITE_ERROR" value="10" enum="Result">
+ <constant name="RESULT_DOWNLOAD_FILE_WRITE_ERROR" value="11" enum="Result">
HTTPRequest couldn't write to the download file.
</constant>
- <constant name="RESULT_REDIRECT_LIMIT_REACHED" value="11" enum="Result">
+ <constant name="RESULT_REDIRECT_LIMIT_REACHED" value="12" enum="Result">
Request reached its maximum redirect limit, see [member max_redirects].
</constant>
- <constant name="RESULT_TIMEOUT" value="12" enum="Result">
+ <constant name="RESULT_TIMEOUT" value="13" enum="Result">
</constant>
</constants>
</class>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 5aa5de1dae..20be20db34 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -233,7 +233,7 @@
<return type="PackedByteArray">
</return>
<description>
- Returns the image's raw data.
+ Returns a copy of the image's raw data.
</description>
</method>
<method name="get_format" qualifiers="const">
diff --git a/doc/classes/ImageTexture3D.xml b/doc/classes/ImageTexture3D.xml
new file mode 100644
index 0000000000..d05082487d
--- /dev/null
+++ b/doc/classes/ImageTexture3D.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ImageTexture3D" inherits="Texture3D" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="create">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="format" type="int" enum="Image.Format">
+ </argument>
+ <argument index="1" name="width" type="int">
+ </argument>
+ <argument index="2" name="height" type="int">
+ </argument>
+ <argument index="3" name="depth" type="int">
+ </argument>
+ <argument index="4" name="use_mipmaps" type="bool">
+ </argument>
+ <argument index="5" name="data" type="Image[]">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="update">
+ <return type="void">
+ </return>
+ <argument index="0" name="data" type="Image[]">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index fc3c3776ce..b05ab5b4d6 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -7,7 +7,7 @@
A singleton that deals with inputs. This includes key presses, mouse buttons and movement, joypads, and input actions. Actions and their events can be set in the [b]Input Map[/b] tab in the [b]Project &gt; Project Settings[/b], or with the [InputMap] class.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/index.html</link>
+ <link title="Inputs tutorial index">https://docs.godotengine.org/en/latest/tutorials/inputs/index.html</link>
</tutorials>
<methods>
<method name="action_press">
@@ -47,8 +47,9 @@
<return type="Vector3">
</return>
<description>
- If the device has an accelerometer, this will return the acceleration. Otherwise, it returns an empty [Vector3].
+ Returns the acceleration of the device's accelerometer, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
Note this method returns an empty [Vector3] when running from the editor even when your device has an accelerometer. You must export your project to a supported device to read values from the accelerometer.
+ [b]Note:[/b] This method only works on iOS, Android, and UWP. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_action_strength" qualifiers="const">
@@ -78,14 +79,16 @@
<return type="Vector3">
</return>
<description>
- If the device has an accelerometer, this will return the gravity. Otherwise, it returns an empty [Vector3].
+ Returns the gravity of the device's accelerometer, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
+ [b]Note:[/b] This method only works on Android and iOS. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_gyroscope" qualifiers="const">
<return type="Vector3">
</return>
<description>
- If the device has a gyroscope, this will return the rate of rotation in rad/s around a device's X, Y, and Z axes. Otherwise, it returns an empty [Vector3].
+ Returns the rotation rate in rad/s around a device's X, Y, and Z axes of the gyroscope, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
+ [b]Note:[/b] This method only works on Android. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_joy_axis" qualifiers="const">
@@ -182,7 +185,8 @@
<return type="Vector3">
</return>
<description>
- If the device has a magnetometer, this will return the magnetic field strength in micro-Tesla for all axes.
+ Returns the the magnetic field strength in micro-Tesla for all axes of the device's magnetometer, if the device has one. Otherwise, the method returns [constant Vector3.ZERO].
+ [b]Note:[/b] This method only works on Android and UWP. On other platforms, it always returns [constant Vector3.ZERO].
</description>
</method>
<method name="get_mouse_button_mask" qualifiers="const">
@@ -417,7 +421,8 @@
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. 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.
+ Captures the mouse. The mouse will be hidden and its position locked at the center of the screen.
+ [b]Note:[/b] If you want to process the mouse's movement in this mode, you need to use [member InputEventMouseMotion.relative].
</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 413e217b45..3663ee98cc 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -7,8 +7,8 @@
Base class of all sort of input event. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
</tutorials>
<methods>
<method name="accumulate">
diff --git a/doc/classes/InputEventAction.xml b/doc/classes/InputEventAction.xml
index 1c38ff8e8f..e0d3e47219 100644
--- a/doc/classes/InputEventAction.xml
+++ b/doc/classes/InputEventAction.xml
@@ -7,7 +7,7 @@
Contains a generic action which can be targeted from several types of inputs. Actions can be created from the [b]Input Map[/b] tab in the [b]Project &gt; Project Settings[/b] menu. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#actions</link>
+ <link title="InputEvent: Actions">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#actions</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml
index 7876bace75..6ab4942f85 100644
--- a/doc/classes/InputEventJoypadButton.xml
+++ b/doc/classes/InputEventJoypadButton.xml
@@ -7,7 +7,7 @@
Input event type for gamepad buttons. For gamepad analog sticks and joysticks, see [InputEventJoypadMotion].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventJoypadMotion.xml b/doc/classes/InputEventJoypadMotion.xml
index bfd961ce1f..2d7787b568 100644
--- a/doc/classes/InputEventJoypadMotion.xml
+++ b/doc/classes/InputEventJoypadMotion.xml
@@ -7,7 +7,7 @@
Stores information about joystick motions. One [InputEventJoypadMotion] represents one axis at a time.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml
index 767e67c615..fe91b9c13e 100644
--- a/doc/classes/InputEventKey.xml
+++ b/doc/classes/InputEventKey.xml
@@ -7,7 +7,7 @@
Stores key presses on the keyboard. Supports key presses, key releases and [member echo] events.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
<method name="get_keycode_with_modifiers" qualifiers="const">
diff --git a/doc/classes/InputEventMouse.xml b/doc/classes/InputEventMouse.xml
index e3c9d688d2..31e82bbaed 100644
--- a/doc/classes/InputEventMouse.xml
+++ b/doc/classes/InputEventMouse.xml
@@ -7,7 +7,7 @@
Stores general mouse events information.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventMouseButton.xml b/doc/classes/InputEventMouseButton.xml
index b83588a877..d7b64a9a2d 100644
--- a/doc/classes/InputEventMouseButton.xml
+++ b/doc/classes/InputEventMouseButton.xml
@@ -7,7 +7,7 @@
Contains mouse click information. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/mouse_and_input_coordinates.html</link>
+ <link title="Mouse and input coordinates">https://docs.godotengine.org/en/latest/tutorials/inputs/mouse_and_input_coordinates.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml
index c36089fe9b..3e64fd63ab 100644
--- a/doc/classes/InputEventMouseMotion.xml
+++ b/doc/classes/InputEventMouseMotion.xml
@@ -8,7 +8,7 @@
[b]Note:[/b] By default, this event is only emitted once per frame rendered at most. If you need more precise input reporting, call [method Input.set_use_accumulated_input] with [code]false[/code] to make events emitted as often as possible. If you use InputEventMouseMotion to draw lines, consider implementing [url=https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to avoid visible gaps in lines if the user is moving the mouse quickly.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/mouse_and_input_coordinates.html</link>
+ <link title="Mouse and input coordinates">https://docs.godotengine.org/en/latest/tutorials/inputs/mouse_and_input_coordinates.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventScreenDrag.xml b/doc/classes/InputEventScreenDrag.xml
index a315e4ddfb..d69f175be8 100644
--- a/doc/classes/InputEventScreenDrag.xml
+++ b/doc/classes/InputEventScreenDrag.xml
@@ -7,7 +7,7 @@
Contains screen drag information. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml
index 16a3cf8353..f497f2fecc 100644
--- a/doc/classes/InputEventScreenTouch.xml
+++ b/doc/classes/InputEventScreenTouch.xml
@@ -8,7 +8,7 @@
Stores multi-touch press/release information. Supports touch press, touch release and [member index] for multi-touch count and order.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml
index cc7de2ca32..667879a922 100644
--- a/doc/classes/InputEventWithModifiers.xml
+++ b/doc/classes/InputEventWithModifiers.xml
@@ -7,7 +7,7 @@
Contains keys events information with modifiers support like [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
+ <link title="InputEvent">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml
index 03212538c9..062ac3869d 100644
--- a/doc/classes/InputMap.xml
+++ b/doc/classes/InputMap.xml
@@ -7,7 +7,7 @@
Manages all [InputEventAction] which can be created/modified from the project settings menu [b]Project &gt; Project Settings &gt; Input Map[/b] or in code with [method add_action] and [method action_add_event]. See [method Node._input].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#inputmap</link>
+ <link title="InputEvent: InputMap">https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#inputmap</link>
</tutorials>
<methods>
<method name="action_add_event">
diff --git a/doc/classes/JavaScript.xml b/doc/classes/JavaScript.xml
index 68f6c32a53..c707a72ee8 100644
--- a/doc/classes/JavaScript.xml
+++ b/doc/classes/JavaScript.xml
@@ -5,9 +5,10 @@
</brief_description>
<description>
The JavaScript singleton is implemented only in the HTML5 export. It's used to access the browser's JavaScript context. This allows interaction with embedding pages or calling third-party JavaScript APIs.
+ [b]Note:[/b] This singleton can be disabled at build-time to improve security. By default, the JavaScript singleton is enabled. Official export templates also have the JavaScript singleton enabled. See [url=https://docs.godotengine.org/en/latest/development/compiling/compiling_for_web.html]Compiling for the Web[/url] in the documentation for more information.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/workflow/export/exporting_for_web.html#calling-javascript-from-script</link>
+ <link title="Exporting for the Web: Calling JavaScript from script">https://docs.godotengine.org/en/latest/getting_started/workflow/export/exporting_for_web.html#calling-javascript-from-script</link>
</tutorials>
<methods>
<method name="eval">
diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml
index 455fdad771..5a1b4630d0 100644
--- a/doc/classes/KinematicBody2D.xml
+++ b/doc/classes/KinematicBody2D.xml
@@ -10,7 +10,7 @@
</description>
<tutorials>
<link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/using_kinematic_body_2d.html</link>
+ <link title="Using KinematicBody2D">https://docs.godotengine.org/en/latest/tutorials/physics/using_kinematic_body_2d.html</link>
</tutorials>
<methods>
<method name="get_floor_normal" qualifiers="const">
diff --git a/doc/classes/KinematicBody3D.xml b/doc/classes/KinematicBody3D.xml
index 01cce907f9..5d9c7fd896 100644
--- a/doc/classes/KinematicBody3D.xml
+++ b/doc/classes/KinematicBody3D.xml
@@ -9,7 +9,7 @@
[b]Kinematic characters:[/b] KinematicBody3D 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>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link>
+ <link title="Kinematic character (2D)">https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link>
</tutorials>
<methods>
<method name="get_axis_lock" qualifiers="const">
diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml
index 2862190d4d..c5f0c2df8c 100644
--- a/doc/classes/Light2D.xml
+++ b/doc/classes/Light2D.xml
@@ -8,7 +8,7 @@
[b]Note:[/b] Light2D can also be used as a mask.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link>
+ <link title="2D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 6979efa569..c022e56a39 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -7,7 +7,7 @@
Light3D is the [i]abstract[/i] base class for light nodes. As it can't be instanced, it shouldn't be used directly. Other types of light nodes inherit from it. Light3D contains the common variables and parameters used for lighting.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
+ <link title="3D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
</tutorials>
<methods>
<method name="get_param" qualifiers="const">
@@ -77,6 +77,8 @@
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false">
If [code]true[/code], the light will cast shadows.
</member>
+ <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="1.0">
+ </member>
<member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="2.0">
Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible.
</member>
@@ -138,10 +140,12 @@
<constant name="PARAM_SHADOW_BLUR" value="16" enum="Param">
Constant for accessing [member shadow_blur].
</constant>
- <constant name="PARAM_TRANSMITTANCE_BIAS" value="17" enum="Param">
+ <constant name="PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="17" enum="Param">
+ </constant>
+ <constant name="PARAM_TRANSMITTANCE_BIAS" value="18" enum="Param">
Constant for accessing [member shadow_transmittance_bias].
</constant>
- <constant name="PARAM_MAX" value="18" enum="Param">
+ <constant name="PARAM_MAX" value="19" enum="Param">
Represents the size of the [enum Param] enum.
</constant>
<constant name="BAKE_DISABLED" value="0" enum="BakeMode">
diff --git a/doc/classes/LightOccluder2D.xml b/doc/classes/LightOccluder2D.xml
index a02f7a0f75..9f128e5942 100644
--- a/doc/classes/LightOccluder2D.xml
+++ b/doc/classes/LightOccluder2D.xml
@@ -7,7 +7,7 @@
Occludes light cast by a Light2D, casting shadows. The LightOccluder2D must be provided with an [OccluderPolygon2D] in order for the shadow to be computed.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link>
+ <link title="2D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/2d/2d_lights_and_shadows.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml
index 13d3355da5..fed936cc2f 100644
--- a/doc/classes/LinkButton.xml
+++ b/doc/classes/LinkButton.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
This kind of button is primarily used when the interaction with the button causes a context change (like linking to a web page).
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index 316315f777..cf1fdb5ba6 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -6,6 +6,7 @@
<description>
Special button that brings up a [PopupMenu] when clicked.
New items can be created inside this [PopupMenu] using [code]get_popup().add_item("My Item Name")[/code]. You can also create them directly from the editor. To do so, select the [MenuButton] node, then in the toolbar at the top of the 2D editor, click [b]Items[/b] then click [b]Add[/b] in the popup. You will be able to give each items new properties.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index 367099e455..1efa72a2b2 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -44,7 +44,7 @@
<return type="AABB">
</return>
<description>
- Returns the smallest [AABB] enclosing this mesh. Not affected by [code]custom_aabb[/code].
+ Returns the smallest [AABB] enclosing this mesh in local space. Not affected by [code]custom_aabb[/code]. See also [method VisualInstance3D.get_transformed_aabb].
[b]Note:[/b] This is only implemented for [ArrayMesh] and [PrimitiveMesh].
</description>
</method>
diff --git a/doc/classes/MeshInstance2D.xml b/doc/classes/MeshInstance2D.xml
index 689f8d83e1..59b312f69a 100644
--- a/doc/classes/MeshInstance2D.xml
+++ b/doc/classes/MeshInstance2D.xml
@@ -7,7 +7,7 @@
Node used for displaying a [Mesh] in 2D. Can be constructed from an existing [Sprite2D] via a tool in the editor toolbar. Select "Sprite2D" then "Convert to Mesh2D", select settings in popup and press "Create Mesh2D".
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_meshes.html</link>
+ <link title="2D meshes">https://docs.godotengine.org/en/latest/tutorials/2d/2d_meshes.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml
index 0f56ab4b95..e1b3ffa2e4 100644
--- a/doc/classes/MultiMesh.xml
+++ b/doc/classes/MultiMesh.xml
@@ -10,15 +10,15 @@
Since instances may have any behavior, the AABB used for visibility must be provided by the user.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/animating_thousands_of_fish.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/optimization/using_multimesh.html</link>
+ <link title="Animating thousands of fish with MultiMeshInstance">https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/animating_thousands_of_fish.html</link>
+ <link title="Optimization using MultiMeshes">https://docs.godotengine.org/en/latest/tutorials/optimization/using_multimesh.html</link>
</tutorials>
<methods>
<method name="get_aabb" qualifiers="const">
<return type="AABB">
</return>
<description>
- Returns the visibility axis-aligned bounding box.
+ Returns the visibility axis-aligned bounding box in local space. See also [method VisualInstance3D.get_transformed_aabb].
</description>
</method>
<method name="get_instance_color" qualifiers="const">
diff --git a/doc/classes/MultiMeshInstance3D.xml b/doc/classes/MultiMeshInstance3D.xml
index cab17c952e..7d8035ba77 100644
--- a/doc/classes/MultiMeshInstance3D.xml
+++ b/doc/classes/MultiMeshInstance3D.xml
@@ -8,9 +8,9 @@
This is useful to optimize the rendering of a high amount of instances of a given mesh (for example trees in a forest or grass strands).
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/animating_thousands_of_fish.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_multi_mesh_instance.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/optimization/using_multimesh.html</link>
+ <link title="Animating thousands of fish with MultiMeshInstance">https://docs.godotengine.org/en/latest/tutorials/3d/vertex_animation/animating_thousands_of_fish.html</link>
+ <link title="Using MultiMeshInstance">https://docs.godotengine.org/en/latest/tutorials/3d/using_multi_mesh_instance.html</link>
+ <link title="Optimization using MultiMeshes">https://docs.godotengine.org/en/latest/tutorials/optimization/using_multimesh.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/Mutex.xml b/doc/classes/Mutex.xml
index 2de1f71867..f5f6308401 100644
--- a/doc/classes/Mutex.xml
+++ b/doc/classes/Mutex.xml
@@ -7,7 +7,7 @@
A synchronization mutex (mutual exclusion). This is used to synchronize multiple [Thread]s, and is equivalent to a binary [Semaphore]. It guarantees that only one thread can ever acquire the lock at a time. A mutex can be used to protect a critical section; however, be careful to avoid deadlocks.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/threads/using_multiple_threads.html</link>
+ <link title="Using multiple threads">https://docs.godotengine.org/en/latest/tutorials/threads/using_multiple_threads.html</link>
</tutorials>
<methods>
<method name="lock">
diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml
index 6deca4394f..a2fa31bf65 100644
--- a/doc/classes/NavigationMesh.xml
+++ b/doc/classes/NavigationMesh.xml
@@ -80,14 +80,17 @@
<member name="agent/height" type="float" setter="set_agent_height" getter="get_agent_height" default="2.0">
</member>
<member name="agent/max_climb" type="float" setter="set_agent_max_climb" getter="get_agent_max_climb" default="0.9">
+ The maximum height difference between two areas for navigation to be generated between them.
</member>
<member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0">
+ The maximum angle a slope can be at for navigation to be generated on it.
</member>
<member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.6">
</member>
<member name="cell/height" type="float" setter="set_cell_height" getter="get_cell_height" default="0.2">
</member>
<member name="cell/size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.3">
+ The size of cells in the [NavigationMesh].
</member>
<member name="detail/sample_distance" type="float" setter="set_detail_sample_distance" getter="get_detail_sample_distance" default="6.0">
</member>
@@ -104,18 +107,25 @@
<member name="filter/low_hanging_obstacles" type="bool" setter="set_filter_low_hanging_obstacles" getter="get_filter_low_hanging_obstacles" default="false">
</member>
<member name="geometry/collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
+ The physics layers used to generate the [NavigationMesh].
</member>
<member name="geometry/parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" default="0">
+ What kind of geomerty is used to generate the [NavigationMesh].
</member>
<member name="geometry/source_geometry_mode" type="int" setter="set_source_geometry_mode" getter="get_source_geometry_mode" default="0">
+ Which geometry is used to generate the [NavigationMesh].
</member>
<member name="geometry/source_group_name" type="StringName" setter="set_source_group_name" getter="get_source_group_name">
+ The name of the group that is used to generate the [NavigationMesh].
</member>
<member name="polygon/verts_per_poly" type="float" setter="set_verts_per_poly" getter="get_verts_per_poly" default="6.0">
+ The number of vertices to use per polygon. Higher values will improve performance at the cost of lower precision.
</member>
<member name="region/merge_size" type="float" setter="set_region_merge_size" getter="get_region_merge_size" default="20.0">
+ If two adjacent regions' edges are separated by a distance lower than this value, the regions will be merged together.
</member>
<member name="region/min_size" type="float" setter="set_region_min_size" getter="get_region_min_size" default="8.0">
+ The minimum size of a region for it to be created.
</member>
<member name="sample_partition_type/sample_partition_type" type="int" setter="set_sample_partition_type" getter="get_sample_partition_type" default="0">
</member>
diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml
index ff97ea926d..7e2a9af59f 100644
--- a/doc/classes/NetworkedMultiplayerPeer.xml
+++ b/doc/classes/NetworkedMultiplayerPeer.xml
@@ -7,7 +7,7 @@
Manages the connection to network peers. Assigns unique IDs to each client connected to the server.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
+ <link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
</tutorials>
<methods>
<method name="get_connection_status" qualifiers="const">
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 8f66c9df38..1548800901 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -17,7 +17,7 @@
[b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]), it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call, Godot will use its [NodePath] (make sure node names are the same on all peers). Also, take a look at the high-level networking tutorial and corresponding demos.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/scenes_and_nodes.html</link>
+ <link title="Scenes and nodes">https://docs.godotengine.org/en/latest/getting_started/step_by_step/scenes_and_nodes.html</link>
</tutorials>
<methods>
<method name="_enter_tree" qualifiers="virtual">
@@ -194,6 +194,7 @@
Finds a descendant of this node whose name matches [code]mask[/code] as in [method String.match] (i.e. case-sensitive, but [code]"*"[/code] matches zero or more characters and [code]"?"[/code] matches any single character except [code]"."[/code]).
[b]Note:[/b] It does not match against the full path, just against individual node names.
If [code]owned[/code] is [code]true[/code], this method only finds nodes whose owner is this node. This is especially important for scenes instantiated through a script, because those scenes don't have an owner.
+ [b]Note:[/b] As this method walks through all the descendants of the node, it is the slowest way to get a reference to another node. Whenever possible, consider using [method get_node] instead. To avoid using [method find_node] too often, consider caching the node reference into a variable.
</description>
</method>
<method name="find_parent" qualifiers="const">
@@ -204,6 +205,7 @@
<description>
Finds the first parent of the current node whose name matches [code]mask[/code] as in [method String.match] (i.e. case-sensitive, but [code]"*"[/code] matches zero or more characters and [code]"?"[/code] matches any single character except [code]"."[/code]).
[b]Note:[/b] It does not match against the full path, just against individual node names.
+ [b]Note:[/b] As this method walks upwards in the scene tree, it can be slow in large, deeply nested scene trees. Whenever possible, consider using [method get_node] instead. To avoid using [method find_parent] too often, consider caching the node reference into a variable.
</description>
</method>
<method name="get_child" qualifiers="const">
@@ -213,6 +215,7 @@
</argument>
<description>
Returns a child node by its index (see [method get_child_count]). This method is often used for iterating all children of a node.
+ Negative indices access the children from the last one.
To access a child node via its name, use [method get_node].
</description>
</method>
@@ -522,7 +525,7 @@
┠╴Menu
┃ ┠╴Label
┃ ┖╴Camera2D
- ┖-SplashScreen
+ ┖╴SplashScreen
┖╴Camera2D
[/codeblock]
</description>
diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml
index d29c556216..987a18f367 100644
--- a/doc/classes/Node2D.xml
+++ b/doc/classes/Node2D.xml
@@ -7,7 +7,7 @@
A 2D game object, with a transform (position, rotation, and scale). All 2D nodes, including physics objects and sprites, inherit from Node2D. Use Node2D as a parent node to move, scale and rotate children in a 2D project. Also gives control of the node's render order.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
+ <link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
</tutorials>
<methods>
<method name="apply_scale">
diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml
index 02b319fb5a..1ef875f606 100644
--- a/doc/classes/Node3D.xml
+++ b/doc/classes/Node3D.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link>
+ <link title="Introduction to 3D">https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link>
</tutorials>
<methods>
<method name="force_update_transform">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 26110df335..a1f12e1a31 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -234,13 +234,6 @@
Returns the number of threads available on the host machine.
</description>
</method>
- <method name="get_splash_tick_msec" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the amount of time in milliseconds it took for the boot logo to appear.
- </description>
- </method>
<method name="get_static_memory_peak_usage" qualifiers="const">
<return type="int">
</return>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index 077067a0f4..50d91c7943 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -395,7 +395,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
- Removes a given entry from the object's metadata.
+ Removes a given entry from the object's metadata. See also [method set_meta].
</description>
</method>
<method name="set">
@@ -464,7 +464,8 @@
<argument index="1" name="value" type="Variant">
</argument>
<description>
- Adds or changes a given entry in the object's metadata. Metadata are serialized, and can take any [Variant] value.
+ Adds, changes or removes a given entry in the object's metadata. Metadata are serialized and can take any [Variant] value.
+ To remove a given entry from the object's metadata, use [method remove_meta]. Metadata is also removed if its value is set to [code]null[/code]. This means you can also use [code]set_meta("name", null)[/code] to remove metadata for [code]"name"[/code].
</description>
</method>
<method name="set_script">
@@ -495,7 +496,7 @@
<description>
Translates a message using translation catalogs configured in the Project Settings. An additional context could be used to specify the translation context.
Only works if message translation is enabled (which it is by default), otherwise it returns the [code]message[/code] unchanged. See [method set_message_translation].
- See <link>https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html</link> for examples of the usage of this method.
+ See [url=https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html]Internationalizing games[/url] for examples of the usage of this method.
</description>
</method>
<method name="tr_n" qualifiers="const">
@@ -514,7 +515,7 @@
Only works if message translation is enabled (which it is by default), otherwise it returns the [code]message[/code] or [code]plural_message[/code] unchanged. See [method set_message_translation].
The number [code]n[/code] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
[b]Note:[/b] Negative and floating-point values usually represent physical entities for which singular and plural don't clearly apply. In such cases, use [method tr].
- See <link>https://docs.godotengine.org/en/latest/tutorials/i18n/localization_using_gettext.html</link> for examples of the usage of this method.
+ See [url=https://docs.godotengine.org/en/latest/tutorials/i18n/localization_using_gettext.html]Localization using gettext[/url] for examples of the usage of this method.
</description>
</method>
</methods>
diff --git a/doc/classes/OmniLight3D.xml b/doc/classes/OmniLight3D.xml
index 000d67e691..dfcb19a287 100644
--- a/doc/classes/OmniLight3D.xml
+++ b/doc/classes/OmniLight3D.xml
@@ -7,7 +7,7 @@
An Omnidirectional light is a type of [Light3D] that emits light in all directions. The light is attenuated by distance and this attenuation can be configured by changing its energy, radius, and attenuation parameters.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
+ <link title="3D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 39d974ec47..510f952fea 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
OptionButton is a type button that provides a selectable list of items when pressed. The item selected becomes the "current" item and is displayed as the button text.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
@@ -217,7 +218,7 @@
<argument index="0" name="index" type="int">
</argument>
<description>
- Emitted the when user navigates to an item using the [code]ui_up[/code] or [code]ui_down[/code] actions. The index of the item selected is passed as argument.
+ Emitted when the user navigates to an item using the [code]ui_up[/code] or [code]ui_down[/code] actions. The index of the item selected is passed as argument.
</description>
</signal>
<signal name="item_selected">
diff --git a/doc/classes/PCKPacker.xml b/doc/classes/PCKPacker.xml
index 314869be49..6b500d5ac3 100644
--- a/doc/classes/PCKPacker.xml
+++ b/doc/classes/PCKPacker.xml
@@ -23,6 +23,8 @@
</argument>
<argument index="1" name="source_path" type="String">
</argument>
+ <argument index="2" name="encrypt" type="bool" default="false">
+ </argument>
<description>
Adds the [code]source_path[/code] file to the current PCK package at the [code]pck_path[/code] internal path (should start with [code]res://[/code]).
</description>
@@ -43,6 +45,10 @@
</argument>
<argument index="1" name="alignment" type="int" default="0">
</argument>
+ <argument index="2" name="key" type="String" default="&quot;&quot;">
+ </argument>
+ <argument index="3" name="encrypt_directory" type="bool" default="false">
+ </argument>
<description>
Creates a new PCK file with the name [code]pck_name[/code]. The [code].pck[/code] file extension isn't added automatically, so it should be part of [code]pck_name[/code] (even though it's not required).
</description>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index 08f8558881..0b43522bce 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -57,6 +57,19 @@
Returns a new [PackedByteArray] with the data decompressed. Set [code]buffer_size[/code] to the size of the uncompressed data. Set the compression mode using one of [enum File.CompressionMode]'s constants.
</description>
</method>
+ <method name="decompress_dynamic">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="max_output_size" type="int">
+ </argument>
+ <argument index="1" name="compression_mode" type="int" default="0">
+ </argument>
+ <description>
+ Returns a new [PackedByteArray] with the data decompressed. Set the compression mode using one of [enum File.CompressionMode]'s constants. [b]This method only accepts gzip and deflate compression modes.[/b]
+ This method is potentially slower than [code]decompress[/code], as it may have to re-allocate it's output buffer multiple times while decompressing, where as [code]decompress[/code] knows it's output buffer size from the beginning.
+ GZIP has a maximal compression ratio of 1032:1, meaning it's very possible for a small compressed payload to decompress to a potentially very large output. To guard against this, you may provide a maximum size this function is allowed to allocate in bytes via [code]max_output_size[/code]. Passing -1 will allow for unbounded output. If any positive value is passed, and the decompression exceeds that amount in bytes, then an error will be returned.
+ </description>
+ </method>
<method name="empty">
<return type="bool">
</return>
@@ -68,14 +81,28 @@
<return type="String">
</return>
<description>
- Returns a copy of the array's contents as [String]. Fast alternative to [method get_string_from_utf8] if the content is ASCII-only. Unlike the UTF-8 function this function maps every byte to a character in the array. Multibyte sequences will not be interpreted correctly. For parsing user input always use [method get_string_from_utf8].
+ Converts ASCII/Latin-1 encoded array to [String]. Fast alternative to [method get_string_from_utf8] if the content is ASCII/Latin-1 only. Unlike the UTF-8 function this function maps every byte to a character in the array. Multibyte sequences will not be interpreted correctly. For parsing user input always use [method get_string_from_utf8].
+ </description>
+ </method>
+ <method name="get_string_from_utf16">
+ <return type="String">
+ </return>
+ <description>
+ Converts UTF-16 encoded array to [String]. If the BOM is missing, system endianness is assumed. Returns empty string if source array is not valid UTF-16 string.
+ </description>
+ </method>
+ <method name="get_string_from_utf32">
+ <return type="String">
+ </return>
+ <description>
+ Converts UTF-32 encoded array to [String]. System endianness is assumed. Returns empty string if source array is not valid UTF-32 string.
</description>
</method>
<method name="get_string_from_utf8">
<return type="String">
</return>
<description>
- 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.
+ Converts UTF-8 encoded array to [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. Returns empty string if source array is not valid UTF-8 string.
</description>
</method>
<method name="has">
diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml
index d04ac5bdce..f6fa3cf38b 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -243,6 +243,14 @@
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees. Applied to X/Z plane and Y/Z planes.
</member>
+ <member name="sub_emitter_amount_at_end" type="int" setter="set_sub_emitter_amount_at_end" getter="get_sub_emitter_amount_at_end">
+ </member>
+ <member name="sub_emitter_frequency" type="float" setter="set_sub_emitter_frequency" getter="get_sub_emitter_frequency">
+ </member>
+ <member name="sub_emitter_keep_velocity" type="bool" setter="set_sub_emitter_keep_velocity" getter="get_sub_emitter_keep_velocity" default="false">
+ </member>
+ <member name="sub_emitter_mode" type="int" setter="set_sub_emitter_mode" getter="get_sub_emitter_mode" enum="ParticlesMaterial.SubEmitterMode" default="0">
+ </member>
<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>
@@ -252,15 +260,6 @@
<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">
- 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">
- Trail particles' size will vary along this [CurveTexture].
- </member>
</members>
<constants>
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
@@ -332,5 +331,15 @@
<constant name="EMISSION_SHAPE_MAX" value="5" enum="EmissionShape">
Represents the size of the [enum EmissionShape] enum.
</constant>
+ <constant name="SUB_EMITTER_DISABLED" value="0" enum="SubEmitterMode">
+ </constant>
+ <constant name="SUB_EMITTER_CONSTANT" value="1" enum="SubEmitterMode">
+ </constant>
+ <constant name="SUB_EMITTER_AT_END" value="2" enum="SubEmitterMode">
+ </constant>
+ <constant name="SUB_EMITTER_AT_COLLISION" value="3" enum="SubEmitterMode">
+ </constant>
+ <constant name="SUB_EMITTER_MAX" value="4" enum="SubEmitterMode">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index 6afbd1ee8e..ca42f5801a 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -7,7 +7,7 @@
PhysicsBody2D is an abstract base class for implementing a physics body. All *Body2D types inherit from it.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
<method name="add_collision_exception_with">
@@ -80,10 +80,10 @@
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this area is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the [member collision_mask] property.
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this area scans for collisions.
+ The physics layers this area scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable" override="true" default="false" />
<member name="layers" type="int" setter="_set_layers" getter="_get_layers">
diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml
index 2301a07a5c..7de65603f9 100644
--- a/doc/classes/PhysicsBody3D.xml
+++ b/doc/classes/PhysicsBody3D.xml
@@ -7,7 +7,7 @@
PhysicsBody3D is an abstract base class for implementing a physics body. All *Body types inherit from it.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
<method name="add_collision_exception_with">
@@ -80,10 +80,10 @@
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this area is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the [member collision_mask] property.
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this area scans for collisions.
+ The physics layers this area scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
</members>
<constants>
diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml
index 30519e11be..dfc0ab909a 100644
--- a/doc/classes/PhysicsDirectBodyState2D.xml
+++ b/doc/classes/PhysicsDirectBodyState2D.xml
@@ -7,7 +7,7 @@
Provides direct access to a physics body in the [PhysicsServer2D], allowing safe changes to physics properties. This object is passed via the direct state callback of rigid/character bodies, and is intended for changing the direct state of that body. See [method RigidBody2D._integrate_forces].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="add_central_force">
diff --git a/doc/classes/PhysicsDirectSpaceState2D.xml b/doc/classes/PhysicsDirectSpaceState2D.xml
index d85d7794dd..676e33601a 100644
--- a/doc/classes/PhysicsDirectSpaceState2D.xml
+++ b/doc/classes/PhysicsDirectSpaceState2D.xml
@@ -7,7 +7,7 @@
Direct access object to a space in the [PhysicsServer2D]. It's used mainly to do queries against objects and areas residing in a given space.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-Casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="cast_motion">
diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml
index ea094dcd90..789e8cc731 100644
--- a/doc/classes/PhysicsDirectSpaceState3D.xml
+++ b/doc/classes/PhysicsDirectSpaceState3D.xml
@@ -7,7 +7,7 @@
Direct access object to a space in the [PhysicsServer3D]. It's used mainly to do queries against objects and areas residing in a given space.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="cast_motion">
diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml
index 63e13954ab..93ca684b95 100644
--- a/doc/classes/PhysicsShapeQueryParameters2D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters2D.xml
@@ -18,7 +18,7 @@
If [code]true[/code], the query will take [PhysicsBody2D]s into account.
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="2147483647">
- The physics layer(s) the query will take into account (as a bitmask).
+ The physics layer(s) the query will take into account (as a bitmask). See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[ ]">
The list of objects or object [RID]s that will be excluded from collisions.
diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml
index f4191d4862..167fb31bb3 100644
--- a/doc/classes/PhysicsShapeQueryParameters3D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters3D.xml
@@ -18,7 +18,7 @@
If [code]true[/code], the query will take [PhysicsBody3D]s into account.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="2147483647">
- The physics layer(s) the query will take into account (as a bitmask).
+ The physics layer(s) the query will take into account (as a bitmask). See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="exclude" type="Array" setter="set_exclude" getter="get_exclude" default="[ ]">
The list of objects or object [RID]s that will be excluded from collisions.
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index ce0680523c..d420e6ccdc 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -7,7 +7,7 @@
Plane represents a normalized plane equation. Basically, "normal" is the normal of the plane (a,b,c normalized), and "d" is the distance from the origin to the plane (in the direction of "normal"). "Over" or "Above" the plane is considered the side of the plane towards where the normal is pointing.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Plane">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index ce55c90c68..b1ec9a222a 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -5,6 +5,8 @@
</brief_description>
<description>
[PopupMenu] is a [Control] that displays a list of options. They are popular in toolbars or context menus.
+ The size of a [PopupMenu] can be limited by using [member Window.max_size]. If the height of the list of items is larger than the maximum height of the [PopupMenu], a [ScrollContainer] within the popup will allow the user to scroll the contents.
+ If no maximum size is set, or if it is set to 0, the [PopupMenu] height will be limited by its parent rect.
</description>
<tutorials>
</tutorials>
@@ -27,14 +29,14 @@
<method name="add_check_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new checkable item and assigns the specified [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new checkable item and assigns the specified [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -61,14 +63,14 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
<argument index="3" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new checkable item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new checkable item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -109,7 +111,7 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
@@ -124,14 +126,14 @@
</return>
<argument index="0" name="texture" type="Texture2D">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="id" type="int" default="-1">
</argument>
<argument index="3" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new item and assigns the specified [ShortCut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new item and assigns the specified [Shortcut] and icon [code]texture[/code] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
</description>
</method>
@@ -186,14 +188,14 @@
<method name="add_radio_check_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a new radio check button and assigns a [ShortCut] to it. Sets the label of the checkbox to the [ShortCut]'s name.
+ Adds a new radio check button and assigns a [Shortcut] to it. Sets the label of the checkbox to the [Shortcut]'s name.
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
[b]Note:[/b] Checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. See [method set_item_checked] for more info on how to control it.
</description>
@@ -210,14 +212,14 @@
<method name="add_shortcut">
<return type="void">
</return>
- <argument index="0" name="shortcut" type="ShortCut">
+ <argument index="0" name="shortcut" type="Shortcut">
</argument>
<argument index="1" name="id" type="int" default="-1">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Adds a [ShortCut].
+ Adds a [Shortcut].
An [code]id[/code] can optionally be provided. If no [code]id[/code] is provided, one will be created from the index.
</description>
</method>
@@ -301,12 +303,12 @@
</description>
</method>
<method name="get_item_shortcut" qualifiers="const">
- <return type="ShortCut">
+ <return type="Shortcut">
</return>
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the [ShortCut] associated with the specified [code]idx[/code] item.
+ Returns the [Shortcut] associated with the specified [code]idx[/code] item.
</description>
</method>
<method name="get_item_submenu" qualifiers="const">
@@ -519,12 +521,12 @@
</return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="shortcut" type="ShortCut">
+ <argument index="1" name="shortcut" type="Shortcut">
</argument>
<argument index="2" name="global" type="bool" default="false">
</argument>
<description>
- Sets a [ShortCut] for the specified item [code]idx[/code].
+ Sets a [Shortcut] for the specified item [code]idx[/code].
</description>
</method>
<method name="set_item_shortcut_disabled">
@@ -535,7 +537,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- Disables the [ShortCut] of the specified index [code]idx[/code].
+ Disables the [Shortcut] of the specified index [code]idx[/code].
</description>
</method>
<method name="set_item_submenu">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 793249afc5..ed8eddda07 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -92,9 +92,12 @@
</argument>
<argument index="1" name="replace_files" type="bool" default="true">
</argument>
+ <argument index="2" name="offset" type="int" default="0">
+ </argument>
<description>
Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success.
[b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code].
+ [b]Note:[/b] The optional [code]offset[/code] parameter can be used to specify the offset in bytes to the start of the resource pack. This is only supported for .pck files.
</description>
</method>
<method name="localize_path" qualifiers="const">
@@ -205,7 +208,8 @@
Icon set in [code].icns[/code] format used on macOS to set the game's icon. This is done automatically on start by calling [method DisplayServer.set_native_icon].
</member>
<member name="application/config/name" type="String" setter="" getter="" default="&quot;&quot;">
- The project's name. It is used both by the Project Manager and by exporters. The project name can be translated by translating its value in localization files.
+ The project's name. It is used both by the Project Manager and by exporters. The project name can be translated by translating its value in localization files. The window title will be set to match the project name automatically on startup.
+ [b]Note:[/b] Changing this value will also change the user data folder's path if [member application/config/use_custom_user_dir] is [code]false[/code]. After renaming the project, you will no longer be able to access existing data in [code]user://[/code] unless you rename the old folder to match the new project name. See [url=https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html]Data paths[/url] in the documentation for more information.
</member>
<member name="application/config/project_settings_override" type="String" setter="" getter="" default="&quot;&quot;">
Specifies a file to override project settings. For example: [code]user://custom_settings.cfg[/code].
@@ -869,7 +873,7 @@
Size of the hash table used for the broad-phase 2D hash grid algorithm.
</member>
<member name="physics/2d/cell_size" type="int" setter="" getter="" default="128">
- Cell size used for the broad-phase 2D hash grid algorithm.
+ Cell size used for the broad-phase 2D hash grid algorithm (in pixels).
</member>
<member name="physics/2d/default_angular_damp" type="float" setter="" getter="" default="1.0">
The default angular damp in 2D.
@@ -1038,6 +1042,9 @@
<member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0">
Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support.
</member>
+ <member name="rendering/quality/glow/use_high_quality" type="bool" setter="" getter="" default="false">
+ Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long.
+ </member>
<member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2">
Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment].
</member>
@@ -1158,6 +1165,16 @@
<member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1">
Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
</member>
+ <member name="rendering/volumetric_fog/directional_shadow_shrink" type="int" setter="" getter="" default="512">
+ </member>
+ <member name="rendering/volumetric_fog/positional_shadow_shrink" type="int" setter="" getter="" default="512">
+ </member>
+ <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="0">
+ </member>
+ <member name="rendering/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128">
+ </member>
+ <member name="rendering/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
+ </member>
<member name="rendering/vram_compression/import_bptc" type="bool" setter="" getter="" default="false">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer.
</member>
@@ -1182,7 +1199,7 @@
<member name="rendering/vulkan/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64">
</member>
<member name="world/2d/cell_size" type="int" setter="" getter="" default="100">
- Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses.
+ Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses (in pixels).
</member>
</members>
<constants>
diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml
index 730edb00d9..2218852dae 100644
--- a/doc/classes/Quat.xml
+++ b/doc/classes/Quat.xml
@@ -9,7 +9,7 @@
Due to its compactness and the way it is stored in memory, certain operations (obtaining axis-angle and performing SLERP, in particular) are more efficient and robust against floating-point errors.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html#interpolating-with-quaternions</link>
+ <link title="Using 3D transforms">https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html#interpolating-with-quaternions</link>
</tutorials>
<methods>
<method name="Quat">
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index 6a11630c0e..e30d7df63f 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -4,14 +4,14 @@
Query the closest object intersecting a ray.
</brief_description>
<description>
- A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 2D space in order to find the closest object along the path of the ray.
- RayCast2D can ignore some objects by adding them to the exception list via [code]add_exception[/code], by setting proper filtering with collision layers, or by filtering object types with type masks.
+ A RayCast represents a line from its origin to its destination position, [member target_position]. It is used to query the 2D space in order to find the closest object along the path of the ray.
+ RayCast2D can ignore some objects by adding them to the exception list via [method add_exception], by setting proper filtering with collision layers, or by filtering object types with type masks.
RayCast2D can be configured to report collisions with [Area2D]s ([member collide_with_areas]) and/or [PhysicsBody2D]s ([member collide_with_bodies]).
Only enabled raycasts will be able to query the space and report collisions.
RayCast2D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="add_exception">
@@ -123,9 +123,6 @@
</method>
</methods>
<members>
- <member name="cast_to" type="Vector2" setter="set_cast_to" getter="get_cast_to" default="Vector2( 0, 50 )">
- The ray's destination point, relative to the RayCast's [code]position[/code].
- </member>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], collision with [Area2D]s will be reported.
</member>
@@ -133,7 +130,7 @@
If [code]true[/code], collision with [PhysicsBody2D]s will be reported.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected.
+ The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
If [code]true[/code], collisions will be reported.
@@ -141,6 +138,9 @@
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
If [code]true[/code], the parent node will be excluded from collision detection.
</member>
+ <member name="target_position" type="Vector2" setter="set_target_position" getter="get_target_position" default="Vector2( 0, 50 )">
+ The ray's destination point, relative to the RayCast's [code]position[/code].
+ </member>
</members>
<constants>
</constants>
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index e7ee1d284f..1d8edf0adb 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -4,14 +4,14 @@
Query the closest object intersecting a ray.
</brief_description>
<description>
- A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 3D space in order to find the closest object along the path of the ray.
- RayCast3D can ignore some objects by adding them to the exception list via [code]add_exception[/code] or by setting proper filtering with collision layers and masks.
+ A RayCast represents a line from its origin to its destination position, [member target_position]. It is used to query the 3D space in order to find the closest object along the path of the ray.
+ RayCast3D can ignore some objects by adding them to the exception list via [method add_exception] or by setting proper filtering with collision layers and masks.
RayCast3D can be configured to report collisions with [Area3D]s ([member collide_with_areas]) and/or [PhysicsBody3D]s ([member collide_with_bodies]).
Only enabled raycasts will be able to query the space and report collisions.
RayCast3D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame), use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="add_exception">
@@ -126,9 +126,6 @@
</method>
</methods>
<members>
- <member name="cast_to" type="Vector3" setter="set_cast_to" getter="get_cast_to" default="Vector3( 0, -1, 0 )">
- The ray's destination point, relative to the RayCast's [code]position[/code].
- </member>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
If [code]true[/code], collision with [Area3D]s will be reported.
</member>
@@ -136,7 +133,7 @@
If [code]true[/code], collision with [PhysicsBody3D]s will be reported.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected.
+ The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
If [code]true[/code], collisions will be reported.
@@ -144,6 +141,9 @@
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" default="true">
If [code]true[/code], collisions will be ignored for this RayCast3D's immediate parent.
</member>
+ <member name="target_position" type="Vector3" setter="set_target_position" getter="get_target_position" default="Vector3( 0, -1, 0 )">
+ The ray's destination point, relative to the RayCast's [code]position[/code].
+ </member>
</members>
<constants>
</constants>
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 8599aad95e..2d1685871d 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -5,10 +5,11 @@
</brief_description>
<description>
[Rect2] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
- It uses floating point coordinates.
+ It uses floating-point coordinates. If you need integer coordinates, use [Rect2i] instead.
+ The 3D counterpart to [Rect2] is [AABB].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Rect2">
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index 7362580c02..809f385f6e 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -5,10 +5,10 @@
</brief_description>
<description>
[Rect2i] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
- It uses integer coordinates.
+ It uses integer coordinates. If you need floating-point coordinates, use [Rect2] instead.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Rect2i">
diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml
index 07d7b646a1..5458b496da 100644
--- a/doc/classes/ReflectionProbe.xml
+++ b/doc/classes/ReflectionProbe.xml
@@ -8,7 +8,7 @@
The [ReflectionProbe] is used to create high-quality reflections at the cost of performance. It can be combined with [GIProbe]s and Screen Space Reflections to achieve high quality reflections. [ReflectionProbe]s render all objects within their [member cull_mask], so updating them can be quite expensive. It is best to update them once with the important static objects and then leave them.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/reflection_probes.html</link>
+ <link title="Reflection probes">https://docs.godotengine.org/en/latest/tutorials/3d/reflection_probes.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 85eaac454f..9c8c964967 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -15,7 +15,7 @@
In 2D, all visible objects are some form of canvas item. In order to be visible, a canvas item needs to be the child of a canvas attached to a viewport, or it needs to be the child of another canvas item that is eventually attached to the canvas.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/optimization/using_servers.html</link>
+ <link title="Optimization using Servers">https://docs.godotengine.org/en/latest/tutorials/optimization/using_servers.html</link>
</tutorials>
<methods>
<method name="black_bars_set_images">
@@ -690,52 +690,19 @@
</argument>
<argument index="1" name="enable" type="bool">
</argument>
- <argument index="2" name="color" type="Color">
- </argument>
- <argument index="3" name="sun_color" type="Color">
- </argument>
- <argument index="4" name="sun_amount" type="float">
- </argument>
- <description>
- Sets the variables to be used with the scene fog. See [Environment] for more details.
- </description>
- </method>
- <method name="environment_set_fog_depth">
- <return type="void">
- </return>
- <argument index="0" name="env" type="RID">
- </argument>
- <argument index="1" name="enable" type="bool">
+ <argument index="2" name="light_color" type="Color">
</argument>
- <argument index="2" name="depth_begin" type="float">
+ <argument index="3" name="light_energy" type="float">
</argument>
- <argument index="3" name="depth_end" type="float">
- </argument>
- <argument index="4" name="depth_curve" type="float">
- </argument>
- <argument index="5" name="transmit" type="bool">
- </argument>
- <argument index="6" name="transmit_curve" type="float">
- </argument>
- <description>
- Sets the variables to be used with the fog depth effect. See [Environment] for more details.
- </description>
- </method>
- <method name="environment_set_fog_height">
- <return type="void">
- </return>
- <argument index="0" name="env" type="RID">
- </argument>
- <argument index="1" name="enable" type="bool">
+ <argument index="4" name="sun_scatter" type="float">
</argument>
- <argument index="2" name="min_height" type="float">
+ <argument index="5" name="density" type="float">
</argument>
- <argument index="3" name="max_height" type="float">
+ <argument index="6" name="height" type="float">
</argument>
- <argument index="4" name="height_curve" type="float">
+ <argument index="7" name="height_density" type="float">
</argument>
<description>
- Sets the variables to be used with the fog height effect. See [Environment] for more details.
</description>
</method>
<method name="environment_set_glow">
@@ -3252,9 +3219,9 @@
<constant name="LIGHT_PARAM_SHADOW_BLUR" value="16" enum="LightParam">
Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible.
</constant>
- <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="17" enum="LightParam">
+ <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="18" enum="LightParam">
</constant>
- <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam">
+ <constant name="LIGHT_PARAM_MAX" value="19" enum="LightParam">
Represents the size of the [enum LightParam] enum.
</constant>
<constant name="LIGHT_BAKE_DISABLED" value="0" enum="LightBakeMode">
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index 34431c5153..726b26fbc7 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -13,8 +13,8 @@
[b]Note:[/b] As soon as a [RichTextLabel] contains at least one [RichTextEffect], it will continuously process the effect unless the project is paused. This may impact battery life negatively.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
- <link>https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
+ <link title="BBCode in RichTextLabel">https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
+ <link title="RichTextEffect test project (third-party)">https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
</tutorials>
<methods>
<method name="_process_custom_fx" qualifiers="virtual">
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index a1c4fcc53c..050f1aab25 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] Unlike [Label], RichTextLabel doesn't have a [i]property[/i] to horizontally align text to the center. Instead, enable [member bbcode_enabled] and surround the text in a [code][center][/code] tag as follows: [code][center]Example[/center][/code]. There is currently no built-in way to vertically align text either, but this can be emulated by relying on anchors/containers and the [member fit_content_height] property.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
+ <link title="BBCode in RichTextLabel">https://docs.godotengine.org/en/latest/tutorials/gui/bbcode_in_richtextlabel.html</link>
</tutorials>
<methods>
<method name="add_image">
@@ -44,6 +44,7 @@
</argument>
<description>
Parses [code]bbcode[/code] and adds tags to the tag stack as needed. Returns the result of the parsing, [constant OK] if successful.
+ [b]Note:[/b] Using this method, you can't close a tag that was opened in a previous [method append_bbcode] call. This is done to improve performance, especially when updating large RichTextLabels since rebuilding the whole BBCode every time would be slower. If you absolutely need to close a tag in a future method call, append the [member bbcode_text] instead of using [method append_bbcode].
</description>
</method>
<method name="clear">
@@ -289,7 +290,7 @@
</member>
<member name="bbcode_text" type="String" setter="set_bbcode" getter="get_bbcode" default="&quot;&quot;">
The label's text in BBCode format. Is not representative of manual modifications to the internal tag stack. Erases changes made by other methods when edited.
- [b]Note:[/b] It is unadvised to use [code]+=[/code] operator with [code]bbcode_text[/code] (e.g. [code]bbcode_text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. Use [method append_bbcode] for adding text instead.
+ [b]Note:[/b] It is unadvised to use the [code]+=[/code] operator with [code]bbcode_text[/code] (e.g. [code]bbcode_text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. Use [method append_bbcode] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call.
</member>
<member name="custom_effects" type="Array" setter="set_effects" getter="get_effects" default="[ ]">
The currently installed custom effects. This is an array of [RichTextEffect]s.
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index 1fbcccdbb5..f3d43b193e 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -129,6 +129,7 @@
</member>
<member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true">
If [code]true[/code], the body can enter sleep mode when there is no movement. See [member sleeping].
+ [b]Note:[/b] A RigidBody2D will never enter sleep mode automatically if its [member mode] is [constant MODE_CHARACTER]. It can still be put to sleep manually by setting its [member sleeping] property to [code]true[/code].
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false">
If [code]true[/code], the body will emit signals when it collides with another RigidBody2D. See also [member contacts_reported].
diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml
index d53d6b001c..e9ebf33aa7 100644
--- a/doc/classes/RigidBody3D.xml
+++ b/doc/classes/RigidBody3D.xml
@@ -11,7 +11,7 @@
With Bullet physics (the default), the center of mass is the RigidBody3D center. With GodotPhysics, the center of mass is the average of the [CollisionShape3D] centers.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
<method name="_integrate_forces" qualifiers="virtual">
@@ -156,6 +156,7 @@
</member>
<member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true">
If [code]true[/code], the body can enter sleep mode when there is no movement. See [member sleeping].
+ [b]Note:[/b] A RigidBody3D will never enter sleep mode automatically if its [member mode] is [constant MODE_CHARACTER]. It can still be put to sleep manually by setting its [member sleeping] property to [code]true[/code].
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false">
If [code]true[/code], the RigidBody3D will emit signals when it collides with another RigidBody3D. See also [member contacts_reported].
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index 00ca5c6e9f..4ea457047f 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -9,8 +9,8 @@
[SceneTree] is the default [MainLoop] implementation used by scenes, and is thus in charge of the game loop.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/scene_tree.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/viewports/multiple_resolutions.html</link>
+ <link title="SceneTree">https://docs.godotengine.org/en/latest/getting_started/step_by_step/scene_tree.html</link>
+ <link title="Multiple resolutions">https://docs.godotengine.org/en/latest/tutorials/viewports/multiple_resolutions.html</link>
</tutorials>
<methods>
<method name="call_group" qualifiers="vararg">
diff --git a/doc/classes/Script.xml b/doc/classes/Script.xml
index 0d94453e52..56272760bd 100644
--- a/doc/classes/Script.xml
+++ b/doc/classes/Script.xml
@@ -8,7 +8,7 @@
The [code]new[/code] method of a script subclass creates a new instance. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/step_by_step/scripting.html</link>
+ <link title="Scripting">https://docs.godotengine.org/en/latest/getting_started/step_by_step/scripting.html</link>
</tutorials>
<methods>
<method name="can_instance" qualifiers="const">
diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml
index 20b0750431..d5a32dd20c 100644
--- a/doc/classes/ScriptEditor.xml
+++ b/doc/classes/ScriptEditor.xml
@@ -86,6 +86,7 @@
<argument index="1" name="base_path" type="String">
</argument>
<description>
+ Opens the script create dialog. The script will extend [code]base_name[/code]. The file extension can be omitted from [code]base_path[/code]. It will be added based on the selected scripting language.
</description>
</method>
<method name="register_syntax_highlighter">
diff --git a/doc/classes/Semaphore.xml b/doc/classes/Semaphore.xml
index c9745acfcd..f311e1c72f 100644
--- a/doc/classes/Semaphore.xml
+++ b/doc/classes/Semaphore.xml
@@ -7,7 +7,7 @@
A synchronization semaphore which can be used to synchronize multiple [Thread]s. Initialized to zero on creation. Be careful to avoid deadlocks. For a binary version, see [Mutex].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/threads/using_multiple_threads.html</link>
+ <link title="Using multiple threads">https://docs.godotengine.org/en/latest/tutorials/threads/using_multiple_threads.html</link>
</tutorials>
<methods>
<method name="post">
diff --git a/doc/classes/Shader.xml b/doc/classes/Shader.xml
index 109c500a63..a717eba438 100644
--- a/doc/classes/Shader.xml
+++ b/doc/classes/Shader.xml
@@ -7,8 +7,8 @@
This class allows you to define a custom shader program that can be used by a [ShaderMaterial]. Shaders allow you to write your own custom behavior for rendering objects or updating particle information. For a detailed explanation and usage, please see the tutorials linked below.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/shading/index.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/shading/your_first_shader/what_are_shaders.html</link>
+ <link title="Shading tutorial index">https://docs.godotengine.org/en/latest/tutorials/shading/index.html</link>
+ <link title="What are shaders?">https://docs.godotengine.org/en/latest/tutorials/shading/your_first_shader/what_are_shaders.html</link>
</tutorials>
<methods>
<method name="get_default_texture_param" qualifiers="const">
diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml
index 7e0e1ce831..b1748703ff 100644
--- a/doc/classes/ShaderMaterial.xml
+++ b/doc/classes/ShaderMaterial.xml
@@ -7,7 +7,7 @@
A material that uses a custom [Shader] program to render either items to screen or process particles. You can create multiple materials for the same shader but configure different values for the uniforms defined in the shader.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/shading/index.html</link>
+ <link title="Shading tutorial index">https://docs.godotengine.org/en/latest/tutorials/shading/index.html</link>
</tutorials>
<methods>
<method name="get_shader_param" qualifiers="const">
diff --git a/doc/classes/Shape2D.xml b/doc/classes/Shape2D.xml
index 5f41d05816..65a37314f6 100644
--- a/doc/classes/Shape2D.xml
+++ b/doc/classes/Shape2D.xml
@@ -7,7 +7,7 @@
Base class for all 2D shapes. All 2D shape types inherit from this.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
<method name="collide">
diff --git a/doc/classes/Shape3D.xml b/doc/classes/Shape3D.xml
index 1af6550dc5..2d8bb5d051 100644
--- a/doc/classes/Shape3D.xml
+++ b/doc/classes/Shape3D.xml
@@ -7,7 +7,7 @@
Base class for all 3D shape resources. Nodes that inherit from this can be used as shapes for a [PhysicsBody3D] or [Area3D] objects.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
+ <link title="Physics introduction">https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/ShortCut.xml b/doc/classes/Shortcut.xml
index 9a2a761969..55bbb083c9 100644
--- a/doc/classes/ShortCut.xml
+++ b/doc/classes/Shortcut.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ShortCut" inherits="Resource" version="4.0">
+<class name="Shortcut" inherits="Resource" version="4.0">
<brief_description>
A shortcut for binding input.
</brief_description>
diff --git a/doc/classes/Skeleton2D.xml b/doc/classes/Skeleton2D.xml
index e1b7d60763..0ddbac9ba4 100644
--- a/doc/classes/Skeleton2D.xml
+++ b/doc/classes/Skeleton2D.xml
@@ -7,7 +7,7 @@
Skeleton2D parents a hierarchy of [Bone2D] objects. It is a requirement of [Bone2D]. Skeleton2D holds a reference to the rest pose of its children and acts as a single point of access to its bones.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/animation/2d_skeletons.html</link>
+ <link title="2D skeletons">https://docs.godotengine.org/en/latest/tutorials/animation/2d_skeletons.html</link>
</tutorials>
<methods>
<method name="get_bone">
diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml
index 24d6609900..d3ab955570 100644
--- a/doc/classes/SoftBody3D.xml
+++ b/doc/classes/SoftBody3D.xml
@@ -7,7 +7,7 @@
A deformable physics body. Used to create elastic or deformable objects such as cloth, rubber, or other flexible materials.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/soft_body.html</link>
+ <link title="SoftBody">https://docs.godotengine.org/en/latest/tutorials/physics/soft_body.html</link>
</tutorials>
<methods>
<method name="add_collision_exception_with">
@@ -82,10 +82,10 @@
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this SoftBody3D is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property.
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this SoftBody3D scans for collisions.
+ The physics layers this SoftBody3D scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.01">
</member>
diff --git a/doc/classes/SpotLight3D.xml b/doc/classes/SpotLight3D.xml
index 423633e583..fc849baa8d 100644
--- a/doc/classes/SpotLight3D.xml
+++ b/doc/classes/SpotLight3D.xml
@@ -7,7 +7,7 @@
A Spotlight is a type of [Light3D] node that emits lights in a specific direction, in the shape of a cone. The light is attenuated through the distance. This attenuation can be configured by changing the energy, radius and attenuation parameters of [Light3D].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
+ <link title="3D lights and shadows">https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/SpringArm3D.xml b/doc/classes/SpringArm3D.xml
index 15caff9eeb..3ffdbebae8 100644
--- a/doc/classes/SpringArm3D.xml
+++ b/doc/classes/SpringArm3D.xml
@@ -47,7 +47,7 @@
</methods>
<members>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The layers against which the collision check shall be done.
+ The layers against which the collision check shall be done. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.01">
When the collision check is made, a candidate length for the SpringArm3D is given.
diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml
index 92f561d7b5..f218631038 100644
--- a/doc/classes/Sprite2D.xml
+++ b/doc/classes/Sprite2D.xml
@@ -44,10 +44,10 @@
If [code]true[/code], texture is flipped vertically.
</member>
<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.
+ Current frame to display from sprite sheet. [member hframes] or [member vframes] 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.
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] 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.
diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml
index f59d5130c9..f9b947fa3d 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -4,8 +4,7 @@
2D sprite node in a 3D world.
</brief_description>
<description>
- A node that displays a 2D texture in a 3D environment. The texture displayed can be a region from a larger atlas texture, or a frame from a sprite sheet animation.
- [b]Note:[/b] There are [url=https://github.com/godotengine/godot/issues/20855]known performance issues[/url] when using [Sprite3D]. Consider using a [MeshInstance3D] with a [QuadMesh] as the mesh instead. You can still have billboarding by enabling billboard properties in the QuadMesh's [StandardMaterial3D].
+ A node that displays a 2D texture in a 3D environment. The texture displayed can be a region from a larger atlas texture, or a frame from a sprite sheet animation. See also [SpriteBase3D] where properties such as the billboard mode are defined.
</description>
<tutorials>
</tutorials>
@@ -13,10 +12,10 @@
</methods>
<members>
<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.
+ Current frame to display from sprite sheet. [member hframes] or [member vframes] 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.
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] 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.
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index 479dc5f94c..44b08408c1 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -4,7 +4,7 @@
2D sprite node in 3D environment.
</brief_description>
<description>
- A node that displays 2D texture information in a 3D environment.
+ A node that displays 2D texture information in a 3D environment. See also [Sprite3D] where many other properties are defined.
</description>
<tutorials>
</tutorials>
@@ -13,6 +13,7 @@
<return type="TriangleMesh">
</return>
<description>
+ Returns a [TriangleMesh] with the sprite's vertices following its current configuration (such as its [member axis] and [member pixel_size]).
</description>
</method>
<method name="get_draw_flag" qualifiers="const">
@@ -39,17 +40,19 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code], the specified flag will be enabled.
+ If [code]true[/code], the specified flag will be enabled. See [enum SpriteBase3D.DrawFlags] for a list of flags.
</description>
</method>
</methods>
<members>
<member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="SpriteBase3D.AlphaCutMode" default="0">
+ The alpha cutting mode to use for the sprite. See [enum AlphaCutMode] for possible values.
</member>
<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="BaseMaterial3D.BillboardMode" default="0">
+ The billboard mode to use for the sprite. See [enum BaseMaterial3D.BillboardMode] for possible values.
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" default="true">
If [code]true[/code], texture will be centered.
@@ -90,16 +93,19 @@
If set, lights in the environment affect the sprite.
</constant>
<constant name="FLAG_DOUBLE_SIDED" value="2" enum="DrawFlags">
- If set, texture can be seen from the back as well, if not, it is invisible when looking at it from behind.
+ If set, texture can be seen from the back as well. If not, the texture is invisible when looking at it from behind.
</constant>
<constant name="FLAG_MAX" value="3" enum="DrawFlags">
Represents the size of the [enum DrawFlags] enum.
</constant>
<constant name="ALPHA_CUT_DISABLED" value="0" enum="AlphaCutMode">
+ This mode performs standard alpha blending. It can display translucent areas, but transparency sorting issues may be visible when multiple transparent materials are overlapping.
</constant>
<constant name="ALPHA_CUT_DISCARD" value="1" enum="AlphaCutMode">
+ This mode only allows fully transparent or fully opaque pixels. Harsh edges will be visible unless some form of screen-space antialiasing is enabled (see [member ProjectSettings.rendering/quality/screen_filters/screen_space_aa]). On the bright side, this mode doesn't suffer from transparency sorting issues when multiple transparent materials are overlapping. This mode is also known as [i]alpha testing[/i] or [i]1-bit transparency[/i].
</constant>
<constant name="ALPHA_CUT_OPAQUE_PREPASS" value="2" enum="AlphaCutMode">
+ This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
</constant>
</constants>
</class>
diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml
index 6e1e1688f4..1c7d84c5a2 100644
--- a/doc/classes/SpriteFrames.xml
+++ b/doc/classes/SpriteFrames.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Sprite frame library for [AnimatedSprite2D]. Contains frames and animation data for playback.
+ [b]Note:[/b] You can associate a set of normal or specular maps by creating additional [SpriteFrames] resources with a [code]_normal[/code] or [code]_specular[/code] suffix. For example, having 3 [SpriteFrames] resources [code]run[/code], [code]run_normal[/code], and [code]run_specular[/code] will make it so the [code]run[/code] animation uses normal and specular maps.
</description>
<tutorials>
</tutorials>
@@ -53,7 +54,7 @@
<argument index="0" name="anim" type="StringName">
</argument>
<description>
- If [code]true[/code], the given animation will loop.
+ Returns [code]true[/code] if the given animation is configured to loop when it finishes playing. Otherwise, returns [code]false[/code].
</description>
</method>
<method name="get_animation_names" qualifiers="const">
diff --git a/doc/classes/StreamPeerSSL.xml b/doc/classes/StreamPeerSSL.xml
index 69e8f67a5e..6a06c0b3f4 100644
--- a/doc/classes/StreamPeerSSL.xml
+++ b/doc/classes/StreamPeerSSL.xml
@@ -7,7 +7,7 @@
SSL stream peer. This object can be used to connect to an SSL server or accept a single SSL client connection.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
+ <link title="SSL certificates">https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
</tutorials>
<methods>
<method name="accept_stream">
diff --git a/doc/classes/StreamTexture3D.xml b/doc/classes/StreamTexture3D.xml
new file mode 100644
index 0000000000..7054a4ee99
--- /dev/null
+++ b/doc/classes/StreamTexture3D.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="StreamTexture3D" inherits="Texture3D" version="4.0">
+ <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>
+ </methods>
+ <members>
+ <member name="load_path" type="String" setter="load" getter="get_load_path" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index ded64761d0..40fff25fc4 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -7,7 +7,7 @@
This is the built-in string class (and the one used by GDScript). It supports Unicode and provides all necessary means for string handling. Strings are reference-counted and use a copy-on-write approach, so passing them around is cheap in resources.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_format_string.html</link>
+ <link title="GDScript format strings">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_format_string.html</link>
</tutorials>
<methods>
<method name="String">
@@ -654,6 +654,17 @@
Returns the string's amount of characters.
</description>
</method>
+ <method name="lpad">
+ <return type="String">
+ </return>
+ <argument index="0" name="min_length" type="int">
+ </argument>
+ <argument index="1" name="character" type="String" default="&quot; &quot;">
+ </argument>
+ <description>
+ Formats a string to be at least [code]min_length[/code] long by adding [code]character[/code]s to the left of the string.
+ </description>
+ </method>
<method name="lstrip">
<return type="String">
</return>
@@ -695,6 +706,15 @@
Returns the MD5 hash of the string as a string.
</description>
</method>
+ <method name="naturalnocasecmp_to">
+ <return type="int">
+ </return>
+ <argument index="0" name="to" type="String">
+ </argument>
+ <description>
+ Performs a case-insensitive natural order 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="nocasecmp_to">
<return type="int">
</return>
@@ -816,6 +836,17 @@
Returns the right side of the string from a given position.
</description>
</method>
+ <method name="rpad">
+ <return type="String">
+ </return>
+ <argument index="0" name="min_length" type="int">
+ </argument>
+ <argument index="1" name="character" type="String" default="&quot; &quot;">
+ </argument>
+ <description>
+ Formats a string to be at least [code]min_length[/code] long by adding [code]character[/code]s to the right of the string.
+ </description>
+ </method>
<method name="rsplit">
<return type="PackedStringArray">
</return>
@@ -953,7 +984,7 @@
<return type="PackedByteArray">
</return>
<description>
- Converts the String (which is a character array) to [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8], as this method assumes that all the characters in the String are ASCII characters.
+ Converts the String (which is a character array) to ASCII/Latin-1 encoded [PackedByteArray] (which is an array of bytes). The conversion is faster compared to [method to_utf8], as this method assumes that all the characters in the String are ASCII/Latin-1 characters, unsupported characters are replaced with spaces.
</description>
</method>
<method name="to_float">
@@ -984,11 +1015,25 @@
Returns the string converted to uppercase.
</description>
</method>
+ <method name="to_utf16">
+ <return type="PackedByteArray">
+ </return>
+ <description>
+ Converts the String (which is an array of characters) to UTF-16 encoded [PackedByteArray] (which is an array of bytes).
+ </description>
+ </method>
+ <method name="to_utf32">
+ <return type="PackedByteArray">
+ </return>
+ <description>
+ Converts the String (which is an array of characters) to UTF-32 encoded [PackedByteArray] (which is an array of bytes).
+ </description>
+ </method>
<method name="to_utf8">
<return type="PackedByteArray">
</return>
<description>
- Converts the String (which is an array of characters) to [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii].
+ Converts the String (which is an array of characters) to UTF-8 encode [PackedByteArray] (which is an array of bytes). The conversion is a bit slower than [method to_ascii], but supports all UTF-8 characters. Therefore, you should prefer this function over [method to_ascii].
</description>
</method>
<method name="trim_prefix">
diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml
index 6014762e3d..c9c7589631 100644
--- a/doc/classes/SubViewport.xml
+++ b/doc/classes/SubViewport.xml
@@ -11,6 +11,7 @@
<members>
<member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="SubViewport.ClearMode" default="0">
The clear mode when the sub-viewport is used as a render target.
+ [b]Note:[/b] This property is intended for 2D usage.
</member>
<member name="render_target_update_mode" type="int" setter="set_update_mode" getter="get_update_mode" enum="SubViewport.UpdateMode" default="2">
The update mode when the sub-viewport is used as a render target.
diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml
index 3fc1db9dc6..ef1f370185 100644
--- a/doc/classes/Tabs.xml
+++ b/doc/classes/Tabs.xml
@@ -36,6 +36,13 @@
Returns [code]true[/code] if the offset buttons (the ones that appear when there's not enough space for all tabs) are visible.
</description>
</method>
+ <method name="get_previous_tab" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the previously active tab index.
+ </description>
+ </method>
<method name="get_select_with_rmb" qualifiers="const">
<return type="bool">
</return>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index d4abac15c0..a23a4936f8 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -9,6 +9,14 @@
<tutorials>
</tutorials>
<methods>
+ <method name="add_gutter">
+ <return type="void">
+ </return>
+ <argument index="0" name="at" type="int" default="-1">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="can_fold" qualifiers="const">
<return type="bool">
</return>
@@ -112,11 +120,34 @@
Folds the given line, if possible (see [method can_fold]).
</description>
</method>
- <method name="get_breakpoints" qualifiers="const">
- <return type="Array">
+ <method name="get_gutter_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_gutter_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_gutter_type" qualifiers="const">
+ <return type="int" enum="TextEdit.GutterType">
</return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_gutter_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
<description>
- Returns an array containing the line number of each breakpoint.
</description>
</method>
<method name="get_line" qualifiers="const">
@@ -135,6 +166,46 @@
Returns the amount of total lines in the text.
</description>
</method>
+ <method name="get_line_gutter_icon" qualifiers="const">
+ <return type="Texture2D">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_line_gutter_item_color">
+ <return type="Color">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_line_gutter_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_line_gutter_text" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_menu" qualifiers="const">
<return type="PopupMenu">
</return>
@@ -202,6 +273,40 @@
Returns whether the line at the specified index is folded or not.
</description>
</method>
+ <method name="is_gutter_clickable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_gutter_drawn" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_gutter_overwritable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_line_gutter_clickable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_line_hidden" qualifiers="const">
<return type="bool">
</return>
@@ -241,11 +346,12 @@
Perform redo operation.
</description>
</method>
- <method name="remove_breakpoints">
+ <method name="remove_gutter">
<return type="void">
</return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
<description>
- Removes all the breakpoints. This will not fire the [signal breakpoint_toggled] signal.
</description>
</method>
<method name="search" qualifiers="const">
@@ -295,6 +401,78 @@
If [member selecting_enabled] is [code]false[/code], no selection will occur.
</description>
</method>
+ <method name="set_gutter_clickable">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="clickable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_custom_draw">
+ <return type="void">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="object" type="Object">
+ </argument>
+ <argument index="2" name="callback" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_draw">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="draw" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_overwritable">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="overwritable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_type">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="type" type="int" enum="TextEdit.GutterType">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_gutter_width">
+ <return type="void">
+ </return>
+ <argument index="0" name="gutter" type="int">
+ </argument>
+ <argument index="1" name="width" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_line">
<return type="void">
</return>
@@ -317,6 +495,66 @@
If [code]true[/code], hides the line of the specified index.
</description>
</method>
+ <method name="set_line_gutter_clickable">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <argument index="2" name="clickable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_gutter_icon">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <argument index="2" name="icon" type="Texture2D">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_gutter_item_color">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <argument index="2" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_gutter_metadata">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <argument index="2" name="metadata" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_line_gutter_text">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="gutter" type="int">
+ </argument>
+ <argument index="2" name="text" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="toggle_fold_line">
<return type="void">
</return>
@@ -351,9 +589,6 @@
</method>
</methods>
<members>
- <member name="breakpoint_gutter" type="bool" setter="set_breakpoint_gutter_enabled" getter="is_breakpoint_gutter_enabled" default="false">
- If [code]true[/code], the breakpoint gutter is visible.
- </member>
<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled" default="false">
If [code]true[/code], the caret (visual cursor) blinks.
</member>
@@ -378,9 +613,6 @@
If [code]true[/code], the "tab" character will have a visible representation.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" />
- <member name="fold_gutter" type="bool" setter="set_draw_fold_gutter" getter="is_drawing_fold_gutter" default="false">
- If [code]true[/code], the fold gutter is visible. This enables folding groups of indented lines.
- </member>
<member name="hiding_enabled" type="bool" setter="set_hiding_enabled" getter="is_hiding_enabled" default="false">
If [code]true[/code], all lines that have been set to hidden by [method set_line_as_hidden], will not be visible.
</member>
@@ -404,10 +636,10 @@
If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
</member>
<member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0">
- The current horizontal scroll value.
+ If there is a horizontal scrollbar this determines the current horizontal scroll value in pixels.
</member>
<member name="scroll_vertical" type="float" setter="set_v_scroll" getter="get_v_scroll" default="0.0">
- The current vertical scroll value.
+ If there is a vertical scrollbar this determines the current vertical scroll value in line numbers, starting at 0 for the top line.
</member>
<member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true">
If [code]true[/code], text can be selected.
@@ -416,9 +648,6 @@
<member name="shortcut_keys_enabled" type="bool" setter="set_shortcut_keys_enabled" getter="is_shortcut_keys_enabled" default="true">
If [code]true[/code], shortcut keys for context menu items are enabled, even if the context menu is disabled.
</member>
- <member name="show_line_numbers" type="bool" setter="set_show_line_numbers" getter="is_show_line_numbers_enabled" default="false">
- If [code]true[/code], line numbers are displayed to the left of the text.
- </member>
<member name="smooth_scrolling" type="bool" setter="set_smooth_scroll_enable" getter="is_smooth_scroll_enabled" default="false">
If [code]true[/code], sets the [code]step[/code] of the scrollbars to [code]0.25[/code] which results in smoother scrolling.
</member>
@@ -438,29 +667,31 @@
</member>
</members>
<signals>
- <signal name="breakpoint_toggled">
- <argument index="0" name="row" type="int">
- </argument>
+ <signal name="cursor_changed">
<description>
- Emitted when a breakpoint is placed via the breakpoint gutter.
+ Emitted when the cursor changes.
</description>
</signal>
- <signal name="cursor_changed">
+ <signal name="gutter_added">
<description>
- Emitted when the cursor changes.
</description>
</signal>
- <signal name="info_clicked">
- <argument index="0" name="row" type="int">
+ <signal name="gutter_clicked">
+ <argument index="0" name="line" type="int">
</argument>
- <argument index="1" name="info" type="String">
+ <argument index="1" name="gutter" type="int">
</argument>
<description>
- Emitted when the info icon is clicked.
</description>
</signal>
- <signal name="line_edited_from">
- <argument index="0" name="line" type="int">
+ <signal name="gutter_removed">
+ <description>
+ </description>
+ </signal>
+ <signal name="lines_edited_from">
+ <argument index="0" name="from_line" type="int">
+ </argument>
+ <argument index="1" name="to_line" type="int">
</argument>
<description>
</description>
@@ -501,6 +732,12 @@
<constant name="SEARCH_BACKWARDS" value="4" enum="SearchFlags">
Search from end to beginning.
</constant>
+ <constant name="GUTTER_TYPE_STRING" value="0" enum="GutterType">
+ </constant>
+ <constant name="GUTTER_TPYE_ICON" value="1" enum="GutterType">
+ </constant>
+ <constant name="GUTTER_TPYE_CUSTOM" value="2" enum="GutterType">
+ </constant>
<constant name="MENU_CUT" value="0" enum="MenuItems">
Cuts (copies and clears) the selected text.
</constant>
@@ -530,14 +767,8 @@
<theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )">
Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled.
</theme_item>
- <theme_item name="bookmark_color" type="Color" default="Color( 0.08, 0.49, 0.98, 1 )">
- Sets the [Color] of the bookmark marker. [member syntax_highlighting] has to be enabled.
- </theme_item>
<theme_item name="brace_mismatch_color" type="Color" default="Color( 1, 0.2, 0.2, 1 )">
</theme_item>
- <theme_item name="breakpoint_color" type="Color" default="Color( 0.8, 0.8, 0.4, 0.2 )">
- Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled.
- </theme_item>
<theme_item name="caret_background_color" type="Color" default="Color( 0, 0, 0, 1 )">
</theme_item>
<theme_item name="caret_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
@@ -565,14 +796,8 @@
<theme_item name="current_line_color" type="Color" default="Color( 0.25, 0.25, 0.26, 0.8 )">
Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled.
</theme_item>
- <theme_item name="executing_line_color" type="Color" default="Color( 0.2, 0.8, 0.2, 0.4 )">
- </theme_item>
<theme_item name="focus" type="StyleBox">
</theme_item>
- <theme_item name="fold" type="Texture2D">
- </theme_item>
- <theme_item name="folded" type="Texture2D">
- </theme_item>
<theme_item name="font" type="Font">
Sets the default [Font].
</theme_item>
@@ -584,9 +809,6 @@
<theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled.
</theme_item>
- <theme_item name="line_number_color" type="Color" default="Color( 0.67, 0.67, 0.67, 0.4 )">
- Sets the [Color] of the line numbers. [member show_line_numbers] has to be enabled.
- </theme_item>
<theme_item name="line_spacing" type="int" default="4">
Sets the spacing between the lines.
</theme_item>
@@ -599,8 +821,6 @@
<theme_item name="read_only" type="StyleBox">
Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled.
</theme_item>
- <theme_item name="safe_line_number_color" type="Color" default="Color( 0.67, 0.78, 0.67, 0.6 )">
- </theme_item>
<theme_item name="selection_color" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )">
Sets the highlight [Color] of text selections.
</theme_item>
diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml
index ffe806cef7..f283efdc3d 100644
--- a/doc/classes/Texture2D.xml
+++ b/doc/classes/Texture2D.xml
@@ -96,7 +96,7 @@
<return type="Image">
</return>
<description>
- Returns an [Image] with the data from this [Texture2D]. [Image]s can be accessed and manipulated directly.
+ Returns an [Image] that is a copy of data from this [Texture2D]. [Image]s can be accessed and manipulated directly.
</description>
</method>
<method name="get_height" qualifiers="const">
diff --git a/doc/classes/Texture3D.xml b/doc/classes/Texture3D.xml
new file mode 100644
index 0000000000..85e940716d
--- /dev/null
+++ b/doc/classes/Texture3D.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Texture3D" inherits="Texture" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_data" qualifiers="const">
+ <return type="Image[]">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_depth" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_format" qualifiers="const">
+ <return type="int" enum="Image.Format">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="has_mipmaps" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/TextureButton.xml b/doc/classes/TextureButton.xml
index a5172586fe..46b008c018 100644
--- a/doc/classes/TextureButton.xml
+++ b/doc/classes/TextureButton.xml
@@ -6,6 +6,7 @@
<description>
[TextureButton] has the same functionality as [Button], except it uses sprites instead of Godot's [Theme] resource. It is faster to create, but it doesn't support localization like more complex [Control]s.
The "normal" state must contain a texture ([member texture_normal]); other textures are optional.
+ See also [BaseButton] which contains common properties and methods associated with this node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index 70a4eda867..2824159f0e 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -8,7 +8,7 @@
Theme resources can alternatively be loaded by writing them in a [code].theme[/code] file, see the documentation for more information.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/gui/gui_skinning.html</link>
+ <link title="GUI skinning">https://docs.godotengine.org/en/latest/tutorials/gui/gui_skinning.html</link>
</tutorials>
<methods>
<method name="clear">
diff --git a/doc/classes/Thread.xml b/doc/classes/Thread.xml
index e0a58d5736..46377ecf20 100644
--- a/doc/classes/Thread.xml
+++ b/doc/classes/Thread.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A unit of execution in a process. Can run methods on [Object]s simultaneously. The use of synchronization via [Mutex] or [Semaphore] is advised if working with shared objects.
+ [b]Note:[/b] Breakpoints won't break on code if it's running in a thread. This is a current limitation of the GDScript debugger.
</description>
<tutorials>
<link title="Using multiple threads">https://docs.godotengine.org/en/latest/tutorials/threads/using_multiple_threads.html</link>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 9df2b656f4..2780545f55 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -7,7 +7,7 @@
Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles (textures plus optional collision, navigation, and/or occluder shapes) which are used to create grid-based maps.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html</link>
+ <link title="Using Tilemaps">https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html</link>
</tutorials>
<methods>
<method name="clear">
@@ -166,7 +166,7 @@
If you need these to be immediately updated, you can call [method update_dirty_quadrants].
Overriding this method also overrides it internally, allowing custom logic to be implemented when tiles are placed/removed:
[codeblock]
- func set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)
+ func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, autotile_coord=Vector2())
# Write your custom logic here.
# To call the default method:
.set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)
@@ -287,10 +287,10 @@
Friction value for static body collisions (see [code]collision_use_kinematic[/code]).
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
- The collision layer(s) for all colliders in the TileMap.
+ The collision layer(s) for all colliders in the TileMap. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The collision mask(s) for all colliders in the TileMap.
+ The collision mask(s) for all colliders in the TileMap. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_use_kinematic" type="bool" setter="set_collision_use_kinematic" getter="get_collision_use_kinematic" default="false">
If [code]true[/code], TileMap collisions will be handled as a kinematic body. If [code]false[/code], collisions will be handled as static body.
diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml
index 26c190bfa9..09dfe56f8f 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -8,9 +8,9 @@
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Matrices and transforms">https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
+ <link title="Using 3D transforms">https://docs.godotengine.org/en/latest/tutorials/3d/using_transforms.html</link>
</tutorials>
<methods>
<method name="Transform">
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index f630df7afe..5da88892fe 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -8,7 +8,7 @@
For more information, read the "Matrices and transforms" documentation article.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
+ <link title="Matrices and transforms">https://docs.godotengine.org/en/latest/tutorials/math/matrices_and_transforms.html</link>
</tutorials>
<methods>
<method name="Transform2D">
diff --git a/doc/classes/Translation.xml b/doc/classes/Translation.xml
index 1989a63362..d286c6cf0c 100644
--- a/doc/classes/Translation.xml
+++ b/doc/classes/Translation.xml
@@ -7,8 +7,8 @@
Translations are resources that can be loaded and unloaded on demand. They map a string to another string.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html</link>
+ <link title="Internationalizing games">https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html</link>
+ <link title="Locales">https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html</link>
</tutorials>
<methods>
<method name="add_message">
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index 3369663af6..664cb3e2e3 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -7,8 +7,8 @@
Server that manages all translations. Translations can be set to it and removed from it.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html</link>
+ <link title="Internationalizing games">https://docs.godotengine.org/en/latest/tutorials/i18n/internationalizing_games.html</link>
+ <link title="Locales">https://docs.godotengine.org/en/latest/tutorials/i18n/locales.html</link>
</tutorials>
<methods>
<method name="add_translation">
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index 042c8d8e67..cd76689ffe 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -50,7 +50,7 @@
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>
- <link>https://docs.godotengine.org/en/latest/development/cpp/variant_class.html</link>
+ <link title="Variant class">https://docs.godotengine.org/en/latest/development/cpp/variant_class.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 11716f511b..44398cabbf 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] In a boolean context, a Vector2 will evaluate to [code]false[/code] if it's equal to [code]Vector2(0, 0)[/code]. Otherwise, a Vector2 will always evaluate to [code]true[/code].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Vector2">
@@ -182,7 +182,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the vector is normalized, and false otherwise.
+ Returns [code]true[/code] if the vector is normalized, [code]false[/code] otherwise.
</description>
</method>
<method name="length">
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index d03db712fc..3ad926210b 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] In a boolean context, a Vector2i will evaluate to [code]false[/code] if it's equal to [code]Vector2i(0, 0)[/code]. Otherwise, a Vector2i will always evaluate to [code]true[/code].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Vector2i">
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 776dfd929e..df5d4f150e 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] In a boolean context, a Vector3 will evaluate to [code]false[/code] if it's equal to [code]Vector3(0, 0, 0)[/code]. Otherwise, a Vector3 will always evaluate to [code]true[/code].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Vector3">
@@ -157,7 +157,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the vector is normalized, and false otherwise.
+ Returns [code]true[/code] if the vector is normalized, [code]false[/code] otherwise.
</description>
</method>
<method name="length">
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index 94551e1c2f..bd7c354241 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -9,7 +9,7 @@
[b]Note:[/b] In a boolean context, a Vector3i will evaluate to [code]false[/code] if it's equal to [code]Vector3i(0, 0, 0)[/code]. Otherwise, a Vector3i will always evaluate to [code]true[/code].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
+ <link title="Math tutorial index">https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
</tutorials>
<methods>
<method name="Vector3i">
diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml
index 91c8ad0a77..60f0a40159 100644
--- a/doc/classes/VideoPlayer.xml
+++ b/doc/classes/VideoPlayer.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Control node for playing video streams using [VideoStream] resources.
- Supported video formats are [url=https://www.webmproject.org/]WebM[/url] ([VideoStreamWebm]), [url=https://www.theora.org/]Ogg Theora[/url] ([VideoStreamTheora]), and any format exposed via a GDNative plugin using [VideoStreamGDNative].
+ Supported video formats are [url=https://www.webmproject.org/]WebM[/url] ([code].webm[/code], [VideoStreamWebm]), [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]), and any format exposed via a GDNative plugin using [VideoStreamGDNative].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 3294ab4cc7..e42c4021ab 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -12,8 +12,8 @@
Finally, viewports can also behave as render targets, in which case they will not be visible unless the associated texture is used to draw.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/viewports/index.html</link>
+ <link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
+ <link title="Viewports tutorial index">https://docs.godotengine.org/en/latest/tutorials/viewports/index.html</link>
</tutorials>
<methods>
<method name="find_world_2d" qualifiers="const">
diff --git a/doc/classes/VisualInstance3D.xml b/doc/classes/VisualInstance3D.xml
index 6451b3f330..01d569d9c8 100644
--- a/doc/classes/VisualInstance3D.xml
+++ b/doc/classes/VisualInstance3D.xml
@@ -13,7 +13,7 @@
<return type="AABB">
</return>
<description>
- Returns the [AABB] (also known as the bounding box) for this [VisualInstance3D].
+ Returns the [AABB] (also known as the bounding box) for this [VisualInstance3D]. See also [method get_transformed_aabb].
</description>
</method>
<method name="get_base" qualifiers="const">
@@ -44,7 +44,7 @@
</return>
<description>
Returns the transformed [AABB] (also known as the bounding box) for this [VisualInstance3D].
- Transformed in this case means the [AABB] plus the position, rotation, and scale of the [Node3D]'s [Transform].
+ Transformed in this case means the [AABB] plus the position, rotation, and scale of the [Node3D]'s [Transform]. See also [method get_aabb].
</description>
</method>
<method name="set_base">
diff --git a/doc/classes/VisualShader.xml b/doc/classes/VisualShader.xml
index 40b0f52469..f03550bd5e 100644
--- a/doc/classes/VisualShader.xml
+++ b/doc/classes/VisualShader.xml
@@ -193,7 +193,6 @@
</method>
</methods>
<members>
- <member name="code" type="String" setter="set_code" getter="get_code" override="true" default="&quot;shader_type spatial;void vertex() {// Output:0}void fragment() {// Output:0}void light() {// Output:0}&quot;" />
<member name="graph_offset" type="Vector2" setter="set_graph_offset" getter="get_graph_offset" default="Vector2( 0, 0 )">
The offset vector of the whole graph.
</member>
@@ -210,7 +209,13 @@
<constant name="TYPE_LIGHT" value="2" enum="Type">
A shader for light calculations.
</constant>
- <constant name="TYPE_MAX" value="3" enum="Type">
+ <constant name="TYPE_EMIT" value="3" enum="Type">
+ </constant>
+ <constant name="TYPE_PROCESS" value="4" enum="Type">
+ </constant>
+ <constant name="TYPE_END" value="5" enum="Type">
+ </constant>
+ <constant name="TYPE_MAX" value="6" enum="Type">
Represents the size of the [enum Type] enum.
</constant>
<constant name="NODE_ID_INVALID" value="-1">
diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index 28d13a7d32..3bb527f3d4 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -6,7 +6,7 @@
<description>
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/shading/visual_shaders.html</link>
+ <link title="VisualShaders">https://docs.godotengine.org/en/latest/tutorials/shading/visual_shaders.html</link>
</tutorials>
<methods>
<method name="get_default_input_values" qualifiers="const">
@@ -57,6 +57,12 @@
Emitted when the node requests an editor refresh. Currently called only in setter of [member VisualShaderNodeTexture.source], [VisualShaderNodeTexture], and [VisualShaderNodeCubemap] (and their derivatives).
</description>
</signal>
+ <signal name="show_port_preview">
+ <argument index="0" name="port_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
</signals>
<constants>
<constant name="PORT_TYPE_SCALAR" value="0" enum="PortType">
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
index 5bd8ec38ed..59b501660a 100644
--- a/doc/classes/VisualShaderNodeCustom.xml
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -5,15 +5,15 @@
</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:
+ In order for the node to be registered as an editor addon, you must use the [code]@tool[/code] annotation and provide a [code]class_name[/code] for your custom script. For example:
[codeblock]
- tool
+ @tool
extends VisualShaderNodeCustom
class_name VisualShaderNodeNoise
[/codeblock]
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/editor/visual_shader_plugins.html</link>
+ <link title="Visual Shader plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/visual_shader_plugins.html</link>
</tutorials>
<methods>
<method name="_get_category" qualifiers="virtual">
diff --git a/doc/classes/VisualShaderNodeInput.xml b/doc/classes/VisualShaderNodeInput.xml
index 9261d0088d..8e819b011c 100644
--- a/doc/classes/VisualShaderNodeInput.xml
+++ b/doc/classes/VisualShaderNodeInput.xml
@@ -7,7 +7,7 @@
Gives access to input variables (built-ins) available for the shader. See the shading reference for the list of available built-ins for each shader type (check [code]Tutorials[/code] section for link).
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html</link>
+ <link title="Shading reference index">https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html</link>
</tutorials>
<methods>
<method name="get_input_real_name" qualifiers="const">
diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml
index 8e389e0b40..0c83ffffe4 100644
--- a/doc/classes/VisualShaderNodeTexture.xml
+++ b/doc/classes/VisualShaderNodeTexture.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTexture" inherits="VisualShaderNode" version="4.0">
<brief_description>
- Performs a texture lookup within the visual shader graph.
+ Performs a 2D texture lookup within the visual shader graph.
</brief_description>
<description>
Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from.
diff --git a/doc/classes/VisualShaderNodeTexture3D.xml b/doc/classes/VisualShaderNodeTexture3D.xml
new file mode 100644
index 0000000000..17929e823e
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTexture3D.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTexture3D" inherits="VisualShaderNodeSample3D" version="4.0">
+ <brief_description>
+ Performs a 3D texture lookup within the visual shader graph.
+ </brief_description>
+ <description>
+ Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="texture" type="Texture3D" setter="set_texture" getter="get_texture">
+ A source texture. Used if [member VisualShaderNodeSample3D.source] is set to [constant VisualShaderNodeSample3D.SOURCE_TEXTURE].
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeTexture3DUniform.xml b/doc/classes/VisualShaderNodeTexture3DUniform.xml
new file mode 100644
index 0000000000..d9e9acf117
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTexture3DUniform.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTexture3DUniform" inherits="VisualShaderNodeTextureUniform" version="4.0">
+ <brief_description>
+ Provides a 3D texture uniform within the visual shader graph.
+ </brief_description>
+ <description>
+ Translated to [code]uniform sampler3D[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml
index e66f21a0e7..b0bfd7f418 100644
--- a/doc/classes/World2D.xml
+++ b/doc/classes/World2D.xml
@@ -7,7 +7,7 @@
Class that has everything pertaining to a 2D world. A physics space, a visual scenario and a sound space. 2D nodes register their resources into the current 2D world.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml
index 6d3b94794e..d804485d4e 100644
--- a/doc/classes/World3D.xml
+++ b/doc/classes/World3D.xml
@@ -7,7 +7,7 @@
Class that has everything pertaining to a world. A physics space, a visual scenario and a sound space. Node3D nodes register their resources into the current world.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
+ <link title="Ray-casting">https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/WorldEnvironment.xml b/doc/classes/WorldEnvironment.xml
index 92b75621c2..f9f0241365 100644
--- a/doc/classes/WorldEnvironment.xml
+++ b/doc/classes/WorldEnvironment.xml
@@ -9,7 +9,7 @@
The [WorldEnvironment] allows the user to specify default lighting parameters (e.g. ambient lighting), various post-processing effects (e.g. SSAO, DOF, Tonemapping), and how to draw the background (e.g. solid color, skybox). Usually, these are added in order to improve the realism/color balance of the scene.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/environment_and_post_processing.html</link>
+ <link title="Environment and post-processing">https://docs.godotengine.org/en/latest/tutorials/3d/environment_and_post_processing.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/XRCamera3D.xml b/doc/classes/XRCamera3D.xml
index 4d86e24daa..b2682f7a90 100644
--- a/doc/classes/XRCamera3D.xml
+++ b/doc/classes/XRCamera3D.xml
@@ -8,7 +8,7 @@
The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml
index 8e80eb9a32..c0f64d9e27 100644
--- a/doc/classes/XRController3D.xml
+++ b/doc/classes/XRController3D.xml
@@ -9,7 +9,7 @@
The position of the controller node is automatically updated by the [XRServer]. This makes this node ideal to add child nodes to visualize the controller.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
<method name="get_controller_name" qualifiers="const">
diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml
index 1985010223..034cb51be3 100644
--- a/doc/classes/XRInterface.xml
+++ b/doc/classes/XRInterface.xml
@@ -8,7 +8,7 @@
Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [XRServer].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
<method name="get_camera_feed_id">
diff --git a/doc/classes/XROrigin3D.xml b/doc/classes/XROrigin3D.xml
index 57cf673d30..3e075e99b9 100644
--- a/doc/classes/XROrigin3D.xml
+++ b/doc/classes/XROrigin3D.xml
@@ -10,7 +10,7 @@
For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index 2f7cc21703..0b57c9478f 100644
--- a/doc/classes/XRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -9,7 +9,7 @@
The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
<method name="get_hand" qualifiers="const">
diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml
index 5e6002aee3..75a05bef17 100644
--- a/doc/classes/XRServer.xml
+++ b/doc/classes/XRServer.xml
@@ -7,7 +7,7 @@
The AR/VR server is the heart of our Advanced and Virtual Reality solution and handles all the processing.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
+ <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
<method name="center_on_hmd">
diff --git a/doc/classes/bool.xml b/doc/classes/bool.xml
index 869fc14d40..ce4d000a9b 100644
--- a/doc/classes/bool.xml
+++ b/doc/classes/bool.xml
@@ -6,36 +6,87 @@
<description>
Boolean is a built-in type. There are two boolean values: [code]true[/code] and [code]false[/code]. You can think of it as an switch with on or off (1 or 0) setting. Booleans are used in programming for logic in condition statements, like [code]if[/code] statements.
Booleans can be directly used in [code]if[/code] statements. The code below demonstrates this on the [code]if can_shoot:[/code] line. You don't need to use [code]== true[/code], you only need [code]if can_shoot:[/code]. Similarly, use [code]if not can_shoot:[/code] rather than [code]== false[/code].
- [codeblock]
- var can_shoot = true
+ [codeblocks]
+ [gdscript]
+ var _can_shoot = true
func shoot():
- if can_shoot:
+ if _can_shoot:
pass # Perform shooting actions here.
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ private bool _canShoot = true;
+
+ public void Shoot()
+ {
+ if (_canShoot)
+ {
+ // Perform shooting actions here.
+ }
+ }
+ [/csharp]
+ [/codeblocks]
The following code will only create a bullet if both conditions are met: action "shoot" is pressed and if [code]can_shoot[/code] is [code]true[/code].
[b]Note:[/b] [code]Input.is_action_pressed("shoot")[/code] is also a boolean that is [code]true[/code] when "shoot" is pressed and [code]false[/code] when "shoot" isn't pressed.
- [codeblock]
- var can_shoot = true
+ [codeblocks]
+ [gdscript]
+ var _can_shoot = true
func shoot():
- if can_shoot and Input.is_action_pressed("shoot"):
+ if _can_shoot and Input.is_action_pressed("shoot"):
create_bullet()
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ private bool _canShoot = true;
+
+ public void Shoot()
+ {
+ if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
+ {
+ CreateBullet();
+ }
+ }
+ [/csharp]
+ [/codeblocks]
The following code will set [code]can_shoot[/code] to [code]false[/code] and start a timer. This will prevent player from shooting until the timer runs out. Next [code]can_shoot[/code] will be set to [code]true[/code] again allowing player to shoot once again.
- [codeblock]
- var can_shoot = true
- onready var cool_down = $CoolDownTimer
+ [gdscript]
+ var _can_shoot = true
+ onready var _cool_down = $CoolDownTimer
func shoot():
- if can_shoot and Input.is_action_pressed("shoot"):
+ if _can_shoot and Input.is_action_pressed("shoot"):
create_bullet()
- can_shoot = false
- cool_down.start()
+ _can_shoot = false
+ _cool_down.start()
func _on_CoolDownTimer_timeout():
- can_shoot = true
- [/codeblock]
+ _can_shoot = true
+ [/gdscript]
+ [csharp]
+ private bool _canShoot = true;
+ private Timer _coolDown;
+
+ public override void _Ready()
+ {
+ _coolDown = GetNode&lt;Timer&gt;("CoolDownTimer");
+ }
+
+ public void Shoot()
+ {
+ if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
+ {
+ CreateBullet();
+ _canShoot = false;
+ _coolDown.Start();
+ }
+ }
+
+ public void OnCoolDownTimerTimeout()
+ {
+ _canShoot = true;
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index b594f652b3..ed147f31cd 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -1041,7 +1041,7 @@ def make_footer(): # type: () -> str
return (
".. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`\n"
".. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`\n"
- ".. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`"
+ ".. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`\n"
)
# fmt: on
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index 0e89e02762..7f352bce28 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -41208,7 +41208,7 @@ msgid ""
"result, it should not be depended upon for reproducible random streams "
"across Godot versions.\n"
"To generate a random float number (within a given range) based on a time-"
-"dependant seed:\n"
+"dependent seed:\n"
"[codeblock]\n"
"var rng = RandomNumberGenerator.new()\n"
"func _ready():\n"
diff --git a/drivers/SCsub b/drivers/SCsub
index c812057138..e2ac9ee01e 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -32,15 +32,6 @@ else:
SConscript("png/SCsub")
SConscript("spirv-reflect/SCsub")
-if env["vsproj"]:
- import os
-
- path = os.getcwd()
- # Change directory so the path resolves correctly in the function call.
- os.chdir("..")
- env.AddToVSProject(env.drivers_sources)
- os.chdir(path)
-
env.add_source_files(env.drivers_sources, "*.cpp")
lib = env.add_library("drivers", env.drivers_sources)
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 7aec0c4071..d1220d126e 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef ALSA_ENABLED
-
#ifndef AUDIO_DRIVER_ALSA_H
#define AUDIO_DRIVER_ALSA_H
+#ifdef ALSA_ENABLED
+
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "servers/audio_server.h"
@@ -88,6 +88,6 @@ public:
~AudioDriverALSA() {}
};
-#endif // AUDIO_DRIVER_ALSA_H
-
#endif // ALSA_ENABLED
+
+#endif // AUDIO_DRIVER_ALSA_H
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index e8ed6df5b0..6aabe8e3fd 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef ALSAMIDI_ENABLED
-
#ifndef MIDI_DRIVER_ALSAMIDI_H
#define MIDI_DRIVER_ALSAMIDI_H
+#ifdef ALSAMIDI_ENABLED
+
#include "core/os/midi_driver.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
@@ -64,5 +64,6 @@ public:
virtual ~MIDIDriverALSAMidi();
};
-#endif // MIDI_DRIVER_ALSAMIDI_H
#endif // ALSAMIDI_ENABLED
+
+#endif // MIDI_DRIVER_ALSAMIDI_H
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 0d2d6b38a7..bdb51b1573 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -42,141 +42,137 @@ class RasterizerSceneDummy : public RasterizerScene {
public:
/* SHADOW ATLAS API */
- RID shadow_atlas_create() { return RID(); }
- void shadow_atlas_set_size(RID p_atlas, int p_size) {}
- void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {}
- bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { return false; }
+ RID shadow_atlas_create() override { return RID(); }
+ void shadow_atlas_set_size(RID p_atlas, int p_size) override {}
+ void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {}
+ bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; }
- void directional_shadow_atlas_set_size(int p_size) {}
- int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
- void set_directional_shadow_count(int p_count) {}
+ void directional_shadow_atlas_set_size(int p_size) override {}
+ int get_directional_light_shadow_size(RID p_light_intance) override { return 0; }
+ void set_directional_shadow_count(int p_count) override {}
/* SDFGI UPDATE */
- virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {}
- virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const { return 0; }
- virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { return AABB(); }
- virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { return 0; }
- virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {}
+ void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
+ int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; }
+ AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); }
+ uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; }
+ void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) override {}
/* SKY API */
- RID sky_create() { return RID(); }
- void sky_set_radiance_size(RID p_sky, int p_radiance_size) {}
- void sky_set_mode(RID p_sky, RS::SkyMode p_samples) {}
- void sky_set_texture(RID p_sky, RID p_panorama) {}
- void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
- void sky_set_material(RID p_sky, RID p_material) {}
- virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { return Ref<Image>(); }
+ RID sky_create() override { return RID(); }
+ void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {}
+ void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {}
+ void sky_set_material(RID p_sky, RID p_material) override {}
+ Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); }
/* ENVIRONMENT API */
- RID environment_create() { return RID(); }
+ RID environment_create() override { return RID(); }
- void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {}
- void environment_set_sky(RID p_env, RID p_sky) {}
- void environment_set_sky_custom_fov(RID p_env, float p_scale) {}
- void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {}
- void environment_set_bg_color(RID p_env, const Color &p_color) {}
- void environment_set_bg_energy(RID p_env, float p_energy) {}
- void environment_set_canvas_max_layer(RID p_env, int p_max_layer) {}
- void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) {}
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) {}
-#endif
+ void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {}
+ void environment_set_sky(RID p_env, RID p_sky) override {}
+ void environment_set_sky_custom_fov(RID p_env, float p_scale) override {}
+ void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override {}
+ void environment_set_bg_color(RID p_env, const Color &p_color) override {}
+ void environment_set_bg_energy(RID p_env, float p_energy) override {}
+ void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {}
+ void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) override {}
- void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {}
- virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) {}
- void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {}
+ void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override {}
+ void environment_glow_set_use_bicubic_upscale(bool p_enable) override {}
+ void environment_glow_set_use_high_quality(bool p_enable) override {}
- void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {}
- virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {}
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {}
- virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {}
+ void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override {}
+ void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {}
+ void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) override {}
+ void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) override {}
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {}
+ void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {}
- virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {}
- virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {}
+ void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {}
+ void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {}
- void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {}
+ void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {}
- void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
+ void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) override {}
- void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {}
- void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
- void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
+ void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) override {}
+ void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {}
+ void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {}
+ void environment_set_volumetric_fog_filter_active(bool p_enable) override {}
+ void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) override {}
+ void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) override {}
- virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { return Ref<Image>(); }
+ Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); }
- bool is_environment(RID p_env) const { return false; }
- RS::EnvironmentBG environment_get_background(RID p_env) const { return RS::ENV_BG_KEEP; }
- int environment_get_canvas_max_layer(RID p_env) const { return 0; }
+ bool is_environment(RID p_env) const override { return false; }
+ RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; }
+ int environment_get_canvas_max_layer(RID p_env) const override { return 0; }
- virtual RID camera_effects_create() { return RID(); }
+ RID camera_effects_create() override { return RID(); }
- virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) {}
- virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) {}
+ void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {}
+ void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {}
- virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) {}
- virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {}
+ void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override {}
+ void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override {}
- virtual void shadows_quality_set(RS::ShadowQuality p_quality) {}
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) {}
+ void shadows_quality_set(RS::ShadowQuality p_quality) override {}
+ void directional_shadow_quality_set(RS::ShadowQuality p_quality) override {}
- RID light_instance_create(RID p_light) { return RID(); }
- void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
- virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {}
- void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) {}
- void light_instance_mark_visible(RID p_light_instance) {}
+ RID light_instance_create(RID p_light) override { return RID(); }
+ void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) override {}
+ void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {}
+ void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {}
+ void light_instance_mark_visible(RID p_light_instance) override {}
- RID reflection_atlas_create() { return RID(); }
- virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {}
+ RID reflection_atlas_create() override { return RID(); }
+ void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {}
- RID reflection_probe_instance_create(RID p_probe) { return RID(); }
- void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {}
- void reflection_probe_release_atlas_index(RID p_instance) {}
- bool reflection_probe_instance_needs_redraw(RID p_instance) { return false; }
- bool reflection_probe_instance_has_reflection(RID p_instance) { return false; }
- bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { return false; }
- bool reflection_probe_instance_postprocess_step(RID p_instance) { return true; }
+ RID reflection_probe_instance_create(RID p_probe) override { return RID(); }
+ void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) override {}
+ void reflection_probe_release_atlas_index(RID p_instance) override {}
+ bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; }
+ bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; }
+ bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; }
+ bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; }
- virtual RID decal_instance_create(RID p_decal) { return RID(); }
- virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) {}
+ RID decal_instance_create(RID p_decal) override { return RID(); }
+ void decal_instance_set_transform(RID p_decal, const Transform &p_transform) override {}
- virtual RID gi_probe_instance_create(RID p_gi_probe) { return RID(); }
- void gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) {}
- void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {}
- virtual bool gi_probe_needs_update(RID p_probe) const { return false; }
- virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {}
+ RID gi_probe_instance_create(RID p_gi_probe) override { return RID(); }
+ void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) override {}
+ bool gi_probe_needs_update(RID p_probe) const override { return false; }
+ void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) override {}
- virtual void gi_probe_set_quality(RS::GIProbeQuality) {}
+ void gi_probe_set_quality(RS::GIProbeQuality) override {}
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {}
- void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
- virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {}
- virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {}
- virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {}
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) override {}
+ void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) override {}
+ void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) override {}
+ void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) override {}
+ void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) override {}
- void set_scene_pass(uint64_t p_pass) {}
- virtual void set_time(double p_time, double p_step) {}
- void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {}
+ void set_scene_pass(uint64_t p_pass) override {}
+ void set_time(double p_time, double p_step) override {}
+ void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {}
- virtual RID render_buffers_create() { return RID(); }
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) {}
+ RID render_buffers_create() override { return RID(); }
+ void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) override {}
- virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {}
- virtual bool screen_space_roughness_limiter_is_active() const { return false; }
+ void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {}
+ bool screen_space_roughness_limiter_is_active() const override { return false; }
- virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {}
- virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {}
+ void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override {}
+ void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override {}
- virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { return TypedArray<Image>(); }
+ TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); }
- bool free(RID p_rid) { return true; }
- virtual void update() {}
- virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {}
+ bool free(RID p_rid) override { return true; }
+ void update() override {}
+ void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {}
RasterizerSceneDummy() {}
~RasterizerSceneDummy() {}
@@ -215,54 +211,54 @@ public:
mutable RID_PtrOwner<DummyTexture> texture_owner;
mutable RID_PtrOwner<DummyMesh> mesh_owner;
- virtual RID texture_2d_create(const Ref<Image> &p_image) { return RID(); }
- virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { return RID(); }
- virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) { return RID(); }
- virtual RID texture_proxy_create(RID p_base) { return RID(); }
+ RID texture_2d_create(const Ref<Image> &p_image) override { return RID(); }
+ RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override { return RID(); }
+ RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override { return RID(); }
+ RID texture_proxy_create(RID p_base) override { return RID(); }
- virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) {}
- virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) {}
- virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) {}
- virtual void texture_proxy_update(RID p_proxy, RID p_base) {}
+ void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
+ void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
+ void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {}
+ void texture_proxy_update(RID p_proxy, RID p_base) override {}
- virtual RID texture_2d_placeholder_create() { return RID(); }
- virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) { return RID(); }
- virtual RID texture_3d_placeholder_create() { return RID(); }
+ RID texture_2d_placeholder_create() override { return RID(); }
+ RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) override { return RID(); }
+ RID texture_3d_placeholder_create() override { return RID(); }
- virtual Ref<Image> texture_2d_get(RID p_texture) const { return Ref<Image>(); }
- virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const { return Ref<Image>(); }
- virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { return Ref<Image>(); }
+ Ref<Image> texture_2d_get(RID p_texture) const override { return Ref<Image>(); }
+ Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); }
+ Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); }
- virtual void texture_replace(RID p_texture, RID p_by_texture) {}
- virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) {}
+ void texture_replace(RID p_texture, RID p_by_texture) override {}
+ void texture_set_size_override(RID p_texture, int p_width, int p_height) override {}
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
- virtual void texture_bind(RID p_texture, uint32_t p_texture_no) = 0;
+ void texture_bind(RID p_texture, uint32_t p_texture_no) = 0;
#endif
- virtual void texture_set_path(RID p_texture, const String &p_path) {}
- virtual String texture_get_path(RID p_texture) const { return String(); }
+ void texture_set_path(RID p_texture, const String &p_path) override {}
+ String texture_get_path(RID p_texture) const override { return String(); }
- virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {}
- virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {}
- virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {}
+ void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {}
+ void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {}
+ void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override {}
- virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) {}
- virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {}
- virtual Size2 texture_size_with_proxy(RID p_proxy) { return Size2(); }
+ void texture_debug_usage(List<RS::TextureInfo> *r_info) override {}
+ void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {}
+ Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); }
- virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) {}
- virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) {}
+ void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+ void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
#if 0
- RID texture_create() {
+ RID texture_create() override {
DummyTexture *texture = memnew(DummyTexture);
ERR_FAIL_COND_V(!texture, RID());
return texture_owner.make_rid(texture);
}
- void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, RenderingServer::TextureType p_type = RS::TEXTURE_TYPE_2D, uint32_t p_flags = RS::TEXTURE_FLAGS_DEFAULT) {
+ void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, RenderingServer::TextureType p_type = RS::TEXTURE_TYPE_2D, uint32_t p_flags = RS::TEXTURE_FLAGS_DEFAULT) override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!t);
t->width = p_width;
@@ -272,7 +268,7 @@ public:
t->image = Ref<Image>(memnew(Image));
t->image->create(p_width, p_height, false, p_format);
}
- void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level) {
+ void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level) override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!t);
t->width = p_image->get_width();
@@ -281,7 +277,7 @@ public:
t->image->create(t->width, t->height, false, t->format, p_image->get_data());
}
- void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_level) {
+ void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_level) override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!t);
@@ -294,100 +290,95 @@ public:
t->image->blit_rect(p_image, Rect2(src_x, src_y, src_w, src_h), Vector2(dst_x, dst_y));
}
- Ref<Image> texture_get_data(RID p_texture, int p_level) const {
+ Ref<Image> texture_get_data(RID p_texture, int p_level) const override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!t, Ref<Image>());
return t->image;
}
- void texture_set_flags(RID p_texture, uint32_t p_flags) {
+ void texture_set_flags(RID p_texture, uint32_t p_flags) override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!t);
t->flags = p_flags;
}
- uint32_t texture_get_flags(RID p_texture) const {
+ uint32_t texture_get_flags(RID p_texture) const override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!t, 0);
return t->flags;
}
- Image::Format texture_get_format(RID p_texture) const {
+ Image::Format texture_get_format(RID p_texture) const override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!t, Image::FORMAT_RGB8);
return t->format;
}
- RenderingServer::TextureType texture_get_type(RID p_texture) const { return RS::TEXTURE_TYPE_2D; }
- uint32_t texture_get_texid(RID p_texture) const { return 0; }
- uint32_t texture_get_width(RID p_texture) const { return 0; }
- uint32_t texture_get_height(RID p_texture) const { return 0; }
- uint32_t texture_get_depth(RID p_texture) const { return 0; }
- void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) {}
- void texture_bind(RID p_texture, uint32_t p_texture_no) {}
+ RenderingServer::TextureType texture_get_type(RID p_texture) const override { return RS::TEXTURE_TYPE_2D; }
+ uint32_t texture_get_texid(RID p_texture) const override { return 0; }
+ uint32_t texture_get_width(RID p_texture) const override { return 0; }
+ uint32_t texture_get_height(RID p_texture) const override { return 0; }
+ uint32_t texture_get_depth(RID p_texture) const override { return 0; }
+ void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) override {}
+ void texture_bind(RID p_texture, uint32_t p_texture_no) override {}
- void texture_set_path(RID p_texture, const String &p_path) {
+ void texture_set_path(RID p_texture, const String &p_path) override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!t);
t->path = p_path;
}
- String texture_get_path(RID p_texture) const {
+ String texture_get_path(RID p_texture) const override {
DummyTexture *t = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!t, String());
return t->path;
}
- void texture_set_shrink_all_x2_on_set_data(bool p_enable) {}
+ void texture_set_shrink_all_x2_on_set_data(bool p_enable) override {}
- void texture_debug_usage(List<RS::TextureInfo> *r_info) {}
+ void texture_debug_usage(List<RS::TextureInfo> *r_info) override {}
- RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const { return RID(); }
+ RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const override { return RID(); }
- void texture_set_detect_3d_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) {}
- void texture_set_detect_srgb_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) {}
- void texture_set_detect_normal_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) {}
+ void texture_set_detect_3d_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
+ void texture_set_detect_srgb_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
+ void texture_set_detect_normal_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
- void textures_keep_original(bool p_enable) {}
+ void textures_keep_original(bool p_enable) override {}
- void texture_set_proxy(RID p_proxy, RID p_base) {}
- virtual Size2 texture_size_with_proxy(RID p_texture) const { return Size2(); }
- void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {}
+ void texture_set_proxy(RID p_proxy, RID p_base) override {}
+ Size2 texture_size_with_proxy(RID p_texture) const override { return Size2(); }
+ void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {}
#endif
- /* SKY API */
-
- RID sky_create() { return RID(); }
- void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
-
/* SHADER API */
- RID shader_create() { return RID(); }
+ RID shader_create() override { return RID(); }
- void shader_set_code(RID p_shader, const String &p_code) {}
- String shader_get_code(RID p_shader) const { return ""; }
- void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {}
+ void shader_set_code(RID p_shader, const String &p_code) override {}
+ String shader_get_code(RID p_shader) const override { return ""; }
+ void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {}
- void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {}
- RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const { return RID(); }
- virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const { return Variant(); }
+ void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) override {}
+ RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const override { return RID(); }
+ Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
/* COMMON MATERIAL API */
- RID material_create() { return RID(); }
+ RID material_create() override { return RID(); }
- void material_set_render_priority(RID p_material, int priority) {}
- void material_set_shader(RID p_shader_material, RID p_shader) {}
+ void material_set_render_priority(RID p_material, int priority) override {}
+ void material_set_shader(RID p_shader_material, RID p_shader) override {}
- void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {}
- Variant material_get_param(RID p_material, const StringName &p_param) const { return Variant(); }
+ void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override {}
+ Variant material_get_param(RID p_material, const StringName &p_param) const override { return Variant(); }
- void material_set_next_pass(RID p_material, RID p_next_material) {}
+ void material_set_next_pass(RID p_material, RID p_next_material) override {}
- bool material_is_animated(RID p_material) { return false; }
- bool material_casts_shadows(RID p_material) { return false; }
- virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {}
- void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) {}
+ bool material_is_animated(RID p_material) override { return false; }
+ bool material_casts_shadows(RID p_material) override { return false; }
+ void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
+ void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) override {}
/* MESH API */
- RID mesh_create() {
+ RID mesh_create() override {
DummyMesh *mesh = memnew(DummyMesh);
ERR_FAIL_COND_V(!mesh, RID());
mesh->blend_shape_count = 0;
@@ -395,10 +386,10 @@ public:
return mesh_owner.make_rid(mesh);
}
- void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {}
+ void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override {}
#if 0
- void mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) {
+ void mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!m);
@@ -415,95 +406,95 @@ public:
s->bone_aabbs = p_bone_aabbs;
}
- void mesh_set_blend_shape_count(RID p_mesh, int p_amount) {
+ void mesh_set_blend_shape_count(RID p_mesh, int p_amount) override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!m);
m->blend_shape_count = p_amount;
}
#endif
- int mesh_get_blend_shape_count(RID p_mesh) const {
+ int mesh_get_blend_shape_count(RID p_mesh) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, 0);
return m->blend_shape_count;
}
- void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) {
+ void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!m);
m->blend_shape_mode = p_mode;
}
- RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const {
+ RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, RS::BLEND_SHAPE_MODE_NORMALIZED);
return m->blend_shape_mode;
}
- void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {}
+ void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {}
- void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {}
- RID mesh_surface_get_material(RID p_mesh, int p_surface) const { return RID(); }
+ void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {}
+ RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); }
#if 0
- int mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
+ int mesh_surface_get_array_len(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, 0);
return m->surfaces[p_surface].vertex_count;
}
- int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
+ int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, 0);
return m->surfaces[p_surface].index_count;
}
- Vector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const {
+ Vector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, Vector<uint8_t>());
return m->surfaces[p_surface].array;
}
- Vector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const {
+ Vector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, Vector<uint8_t>());
return m->surfaces[p_surface].index_array;
}
- uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const {
+ uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, 0);
return m->surfaces[p_surface].format;
}
- RS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
+ RS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, RS::PRIMITIVE_POINTS);
return m->surfaces[p_surface].primitive;
}
- AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const {
+ AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, AABB());
return m->surfaces[p_surface].aabb;
}
- Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const {
+ Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, Vector<Vector<uint8_t> >());
return m->surfaces[p_surface].blend_shapes;
}
- Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
+ Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, Vector<AABB>());
return m->surfaces[p_surface].bone_aabbs;
}
- void mesh_remove_surface(RID p_mesh, int p_index) {
+ void mesh_remove_surface(RID p_mesh, int p_index) override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!m);
ERR_FAIL_COND(p_index >= m->surfaces.size());
@@ -512,203 +503,198 @@ public:
}
#endif
- RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const { return RS::SurfaceData(); }
- int mesh_get_surface_count(RID p_mesh) const {
+ RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { return RS::SurfaceData(); }
+ int mesh_get_surface_count(RID p_mesh) const override {
DummyMesh *m = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!m, 0);
return m->surfaces.size();
}
- void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {}
- AABB mesh_get_custom_aabb(RID p_mesh) const { return AABB(); }
+ void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {}
+ AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); }
- AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) { return AABB(); }
- void mesh_clear(RID p_mesh) {}
+ AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); }
+ void mesh_clear(RID p_mesh) override {}
/* MULTIMESH API */
- virtual RID multimesh_create() { return RID(); }
+ RID multimesh_create() override { return RID(); }
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) {}
- int multimesh_get_instance_count(RID p_multimesh) const { return 0; }
+ void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {}
+ int multimesh_get_instance_count(RID p_multimesh) const override { return 0; }
- void multimesh_set_mesh(RID p_multimesh, RID p_mesh) {}
- void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {}
- void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {}
- void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {}
- void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {}
+ void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {}
+ void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) override {}
+ void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) override {}
+ void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) override {}
+ void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) override {}
- RID multimesh_get_mesh(RID p_multimesh) const { return RID(); }
- AABB multimesh_get_aabb(RID p_multimesh) const { return AABB(); }
+ RID multimesh_get_mesh(RID p_multimesh) const override { return RID(); }
+ AABB multimesh_get_aabb(RID p_multimesh) const override { return AABB(); }
- Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const { return Transform(); }
- Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { return Transform2D(); }
- Color multimesh_instance_get_color(RID p_multimesh, int p_index) const { return Color(); }
- Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { return Color(); }
- virtual void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) {}
- virtual Vector<float> multimesh_get_buffer(RID p_multimesh) const { return Vector<float>(); }
+ Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const override { return Transform(); }
+ Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const override { return Transform2D(); }
+ Color multimesh_instance_get_color(RID p_multimesh, int p_index) const override { return Color(); }
+ Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const override { return Color(); }
+ void multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) override {}
+ Vector<float> multimesh_get_buffer(RID p_multimesh) const override { return Vector<float>(); }
- void multimesh_set_visible_instances(RID p_multimesh, int p_visible) {}
- int multimesh_get_visible_instances(RID p_multimesh) const { return 0; }
+ void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override {}
+ int multimesh_get_visible_instances(RID p_multimesh) const override { return 0; }
/* IMMEDIATE API */
- RID immediate_create() { return RID(); }
- void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {}
- void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {}
- void immediate_normal(RID p_immediate, const Vector3 &p_normal) {}
- void immediate_tangent(RID p_immediate, const Plane &p_tangent) {}
- void immediate_color(RID p_immediate, const Color &p_color) {}
- void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {}
- void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {}
- void immediate_end(RID p_immediate) {}
- void immediate_clear(RID p_immediate) {}
- void immediate_set_material(RID p_immediate, RID p_material) {}
- RID immediate_get_material(RID p_immediate) const { return RID(); }
- AABB immediate_get_aabb(RID p_immediate) const { return AABB(); }
+ RID immediate_create() override { return RID(); }
+ void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) override {}
+ void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) override {}
+ void immediate_normal(RID p_immediate, const Vector3 &p_normal) override {}
+ void immediate_tangent(RID p_immediate, const Plane &p_tangent) override {}
+ void immediate_color(RID p_immediate, const Color &p_color) override {}
+ void immediate_uv(RID p_immediate, const Vector2 &tex_uv) override {}
+ void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) override {}
+ void immediate_end(RID p_immediate) override {}
+ void immediate_clear(RID p_immediate) override {}
+ void immediate_set_material(RID p_immediate, RID p_material) override {}
+ RID immediate_get_material(RID p_immediate) const override { return RID(); }
+ AABB immediate_get_aabb(RID p_immediate) const override { return AABB(); }
/* SKELETON API */
- RID skeleton_create() { return RID(); }
- void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) {}
- void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {}
- void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {}
- int skeleton_get_bone_count(RID p_skeleton) const { return 0; }
- void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {}
- Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { return Transform(); }
- void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {}
- Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { return Transform2D(); }
+ RID skeleton_create() override { return RID(); }
+ void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {}
+ void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override {}
+ int skeleton_get_bone_count(RID p_skeleton) const override { return 0; }
+ void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) override {}
+ Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override { return Transform(); }
+ void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override {}
+ Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override { return Transform2D(); }
/* Light API */
- RID light_create(RS::LightType p_type) { return RID(); }
+ RID light_create(RS::LightType p_type) override { return RID(); }
- RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); }
- RID omni_light_create() { return light_create(RS::LIGHT_OMNI); }
- RID spot_light_create() { return light_create(RS::LIGHT_SPOT); }
+ void light_set_color(RID p_light, const Color &p_color) override {}
+ void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {}
+ void light_set_shadow(RID p_light, bool p_enabled) override {}
+ void light_set_shadow_color(RID p_light, const Color &p_color) override {}
+ void light_set_projector(RID p_light, RID p_texture) override {}
+ void light_set_negative(RID p_light, bool p_enable) override {}
+ void light_set_cull_mask(RID p_light, uint32_t p_mask) override {}
+ void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override {}
+ void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override {}
+ void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {}
- void light_set_color(RID p_light, const Color &p_color) {}
- void light_set_param(RID p_light, RS::LightParam p_param, float p_value) {}
- void light_set_shadow(RID p_light, bool p_enabled) {}
- void light_set_shadow_color(RID p_light, const Color &p_color) {}
- void light_set_projector(RID p_light, RID p_texture) {}
- void light_set_negative(RID p_light, bool p_enable) {}
- void light_set_cull_mask(RID p_light, uint32_t p_mask) {}
- void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {}
- void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {}
- void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {}
+ void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) override {}
- void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {}
+ void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) override {}
+ void light_directional_set_blend_splits(RID p_light, bool p_enable) override {}
+ bool light_directional_get_blend_splits(RID p_light) const override { return false; }
+ void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) override {}
+ RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const override { return RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; }
- void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {}
- void light_directional_set_blend_splits(RID p_light, bool p_enable) {}
- bool light_directional_get_blend_splits(RID p_light) const { return false; }
- void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) {}
- RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const { return RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; }
+ RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
+ RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; }
- RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
- RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; }
+ bool light_has_shadow(RID p_light) const override { return false; }
- bool light_has_shadow(RID p_light) const { return false; }
-
- RS::LightType light_get_type(RID p_light) const { return RS::LIGHT_OMNI; }
- AABB light_get_aabb(RID p_light) const { return AABB(); }
- float light_get_param(RID p_light, RS::LightParam p_param) { return 0.0; }
- Color light_get_color(RID p_light) { return Color(); }
- virtual RS::LightBakeMode light_get_bake_mode(RID p_light) { return RS::LIGHT_BAKE_DISABLED; }
- virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) { return 0; }
- uint64_t light_get_version(RID p_light) const { return 0; }
+ RS::LightType light_get_type(RID p_light) const override { return RS::LIGHT_OMNI; }
+ AABB light_get_aabb(RID p_light) const override { return AABB(); }
+ float light_get_param(RID p_light, RS::LightParam p_param) override { return 0.0; }
+ Color light_get_color(RID p_light) override { return Color(); }
+ RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; }
+ uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
+ uint64_t light_get_version(RID p_light) const override { return 0; }
/* PROBE API */
- RID reflection_probe_create() { return RID(); }
-
- void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {}
- void reflection_probe_set_intensity(RID p_probe, float p_intensity) {}
- void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {}
- void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {}
- void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {}
- void reflection_probe_set_max_distance(RID p_probe, float p_distance) {}
- void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {}
- void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {}
- void reflection_probe_set_as_interior(RID p_probe, bool p_enable) {}
- void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {}
- void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {}
- void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {}
- void reflection_probe_set_resolution(RID p_probe, int p_resolution) {}
-
- AABB reflection_probe_get_aabb(RID p_probe) const { return AABB(); }
- RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
- uint32_t reflection_probe_get_cull_mask(RID p_probe) const { return 0; }
- Vector3 reflection_probe_get_extents(RID p_probe) const { return Vector3(); }
- Vector3 reflection_probe_get_origin_offset(RID p_probe) const { return Vector3(); }
- float reflection_probe_get_origin_max_distance(RID p_probe) const { return 0.0; }
- bool reflection_probe_renders_shadows(RID p_probe) const { return false; }
-
- virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {}
- virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {}
+ RID reflection_probe_create() override { return RID(); }
+
+ void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {}
+ void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {}
+ void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {}
+ void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override {}
+ void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override {}
+ void reflection_probe_set_max_distance(RID p_probe, float p_distance) override {}
+ void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override {}
+ void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override {}
+ void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override {}
+ void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override {}
+ void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override {}
+ void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override {}
+ void reflection_probe_set_resolution(RID p_probe, int p_resolution) override {}
+
+ AABB reflection_probe_get_aabb(RID p_probe) const override { return AABB(); }
+ RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
+ uint32_t reflection_probe_get_cull_mask(RID p_probe) const override { return 0; }
+ Vector3 reflection_probe_get_extents(RID p_probe) const override { return Vector3(); }
+ Vector3 reflection_probe_get_origin_offset(RID p_probe) const override { return Vector3(); }
+ float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
+ bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
+
+ void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {}
+ void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {}
/* DECAL API */
- virtual RID decal_create() { return RID(); }
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) {}
- virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {}
- virtual void decal_set_emission_energy(RID p_decal, float p_energy) {}
- virtual void decal_set_albedo_mix(RID p_decal, float p_mix) {}
- virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) {}
- virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) {}
- virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {}
- virtual void decal_set_fade(RID p_decal, float p_above, float p_below) {}
- virtual void decal_set_normal_fade(RID p_decal, float p_fade) {}
+ RID decal_create() override { return RID(); }
+ void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
+ void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
+ void decal_set_emission_energy(RID p_decal, float p_energy) override {}
+ void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
+ void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
+ void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
+ void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
+ void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
+ void decal_set_normal_fade(RID p_decal, float p_fade) override {}
- virtual AABB decal_get_aabb(RID p_decal) const { return AABB(); }
+ AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
/* GI PROBE API */
- RID gi_probe_create() { return RID(); }
+ RID gi_probe_create() override { return RID(); }
- virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {}
+ void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {}
- virtual AABB gi_probe_get_bounds(RID p_gi_probe) const { return AABB(); }
- virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const { return Vector3i(); }
- virtual Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const { return Vector<uint8_t>(); }
- virtual Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const { return Vector<uint8_t>(); }
- virtual Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const { return Vector<uint8_t>(); }
+ AABB gi_probe_get_bounds(RID p_gi_probe) const override { return AABB(); }
+ Vector3i gi_probe_get_octree_size(RID p_gi_probe) const override { return Vector3i(); }
+ Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const override { return Vector<uint8_t>(); }
+ Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const override { return Vector<uint8_t>(); }
+ Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const override { return Vector<uint8_t>(); }
- virtual Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const { return Vector<int>(); }
- virtual Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const { return Transform(); }
+ Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const override { return Vector<int>(); }
+ Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const override { return Transform(); }
- virtual void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) {}
- virtual float gi_probe_get_dynamic_range(RID p_gi_probe) const { return 0; }
+ void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) override {}
+ float gi_probe_get_dynamic_range(RID p_gi_probe) const override { return 0; }
- virtual void gi_probe_set_propagation(RID p_gi_probe, float p_range) {}
- virtual float gi_probe_get_propagation(RID p_gi_probe) const { return 0; }
+ void gi_probe_set_propagation(RID p_gi_probe, float p_range) override {}
+ float gi_probe_get_propagation(RID p_gi_probe) const override { return 0; }
- void gi_probe_set_energy(RID p_gi_probe, float p_range) {}
- float gi_probe_get_energy(RID p_gi_probe) const { return 0.0; }
+ void gi_probe_set_energy(RID p_gi_probe, float p_range) override {}
+ float gi_probe_get_energy(RID p_gi_probe) const override { return 0.0; }
- virtual void gi_probe_set_ao(RID p_gi_probe, float p_ao) {}
- virtual float gi_probe_get_ao(RID p_gi_probe) const { return 0; }
+ void gi_probe_set_ao(RID p_gi_probe, float p_ao) override {}
+ float gi_probe_get_ao(RID p_gi_probe) const override { return 0; }
- virtual void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) {}
- virtual float gi_probe_get_ao_size(RID p_gi_probe) const { return 0; }
+ void gi_probe_set_ao_size(RID p_gi_probe, float p_strength) override {}
+ float gi_probe_get_ao_size(RID p_gi_probe) const override { return 0; }
- void gi_probe_set_bias(RID p_gi_probe, float p_range) {}
- float gi_probe_get_bias(RID p_gi_probe) const { return 0.0; }
+ void gi_probe_set_bias(RID p_gi_probe, float p_range) override {}
+ float gi_probe_get_bias(RID p_gi_probe) const override { return 0.0; }
- void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) {}
- float gi_probe_get_normal_bias(RID p_gi_probe) const { return 0.0; }
+ void gi_probe_set_normal_bias(RID p_gi_probe, float p_range) override {}
+ float gi_probe_get_normal_bias(RID p_gi_probe) const override { return 0.0; }
- void gi_probe_set_interior(RID p_gi_probe, bool p_enable) {}
- bool gi_probe_is_interior(RID p_gi_probe) const { return false; }
+ void gi_probe_set_interior(RID p_gi_probe, bool p_enable) override {}
+ bool gi_probe_is_interior(RID p_gi_probe) const override { return false; }
- virtual void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) {}
- virtual bool gi_probe_is_using_two_bounces(RID p_gi_probe) const { return false; }
+ void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) override {}
+ bool gi_probe_is_using_two_bounces(RID p_gi_probe) const override { return false; }
- virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) {}
- virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const { return 0; }
+ void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) override {}
+ float gi_probe_get_anisotropy_strength(RID p_gi_probe) const override { return 0; }
- uint32_t gi_probe_get_version(RID p_gi_probe) { return 0; }
+ uint32_t gi_probe_get_version(RID p_gi_probe) override { return 0; }
/* LIGHTMAP CAPTURE */
#if 0
@@ -716,19 +702,19 @@ public:
SelfList<RasterizerScene::InstanceBase>::List instance_list;
- _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) {
+ _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override {
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
- while (instances) {
+ while (instances) override {
//instances->self()->base_changed(p_aabb, p_materials);
instances = instances->next();
}
}
- _FORCE_INLINE_ void instance_remove_deps() {
+ _FORCE_INLINE_ void instance_remove_deps() override {
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
- while (instances) {
+ while (instances) override {
SelfList<RasterizerScene::InstanceBase> *next = instances->next();
//instances->self()->base_removed();
@@ -736,8 +722,8 @@ public:
}
}
- Instantiable() {}
- virtual ~Instantiable() {
+ Instantiable() override {}
+ ~Instantiable() override {
}
};
@@ -748,126 +734,129 @@ public:
Transform cell_xform;
int cell_subdiv;
float energy;
- LightmapCapture() {
+ LightmapCapture() override {
energy = 1.0;
cell_subdiv = 1;
}
};
mutable RID_PtrOwner<LightmapCapture> lightmap_capture_data_owner;
- void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {}
- AABB lightmap_capture_get_bounds(RID p_capture) const { return AABB(); }
- void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {}
- RID lightmap_capture_create() {
+ void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) override {}
+ AABB lightmap_capture_get_bounds(RID p_capture) const override { return AABB(); }
+ void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) override {}
+ RID lightmap_capture_create() override {
LightmapCapture *capture = memnew(LightmapCapture);
return lightmap_capture_data_owner.make_rid(capture);
}
- Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const {
+ Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const override {
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND_V(!capture, Vector<uint8_t>());
return Vector<uint8_t>();
}
- void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) {}
- Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const { return Transform(); }
- void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) {}
- int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const { return 0; }
- void lightmap_capture_set_energy(RID p_capture, float p_energy) {}
- float lightmap_capture_get_energy(RID p_capture) const { return 0.0; }
- const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const {
+ void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) override {}
+ Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const override { return Transform(); }
+ void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) override {}
+ int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const override { return 0; }
+ void lightmap_capture_set_energy(RID p_capture, float p_energy) override {}
+ float lightmap_capture_get_energy(RID p_capture) const override { return 0.0; }
+ const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const override {
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND_V(!capture, nullptr);
return &capture->octree;
}
#endif
- virtual RID lightmap_create() { return RID(); }
-
- virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {}
- virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {}
- virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {}
- virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {}
- virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const { return PackedVector3Array(); }
- virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const { return PackedColorArray(); }
- virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { return PackedInt32Array(); }
- virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { return PackedInt32Array(); }
- virtual AABB lightmap_get_aabb(RID p_lightmap) const { return AABB(); }
- virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {}
- virtual bool lightmap_is_interior(RID p_lightmap) const { return false; }
- virtual void lightmap_set_probe_capture_update_speed(float p_speed) {}
- virtual float lightmap_get_probe_capture_update_speed() const { return 0; }
+ RID lightmap_create() override { return RID(); }
+
+ void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
+ void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
+ void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {}
+ void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) override {}
+ PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const override { return PackedVector3Array(); }
+ PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const override { return PackedColorArray(); }
+ PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const override { return PackedInt32Array(); }
+ PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const override { return PackedInt32Array(); }
+ AABB lightmap_get_aabb(RID p_lightmap) const override { return AABB(); }
+ void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) override {}
+ bool lightmap_is_interior(RID p_lightmap) const override { return false; }
+ void lightmap_set_probe_capture_update_speed(float p_speed) override {}
+ float lightmap_get_probe_capture_update_speed() const override { return 0; }
/* PARTICLES */
- RID particles_create() { return RID(); }
-
- void particles_set_emitting(RID p_particles, bool p_emitting) {}
- void particles_set_amount(RID p_particles, int p_amount) {}
- void particles_set_lifetime(RID p_particles, float p_lifetime) {}
- void particles_set_one_shot(RID p_particles, bool p_one_shot) {}
- void particles_set_pre_process_time(RID p_particles, float p_time) {}
- void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) {}
- void particles_set_randomness_ratio(RID p_particles, float p_ratio) {}
- void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {}
- void particles_set_speed_scale(RID p_particles, float p_scale) {}
- void particles_set_use_local_coordinates(RID p_particles, bool p_enable) {}
- void particles_set_process_material(RID p_particles, RID p_material) {}
- void particles_set_fixed_fps(RID p_particles, int p_fps) {}
- void particles_set_fractional_delta(RID p_particles, bool p_enable) {}
- void particles_restart(RID p_particles) {}
-
- void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {}
-
- void particles_set_draw_passes(RID p_particles, int p_count) {}
- void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {}
-
- void particles_request_process(RID p_particles) {}
- AABB particles_get_current_aabb(RID p_particles) { return AABB(); }
- AABB particles_get_aabb(RID p_particles) const { return AABB(); }
-
- void particles_set_emission_transform(RID p_particles, const Transform &p_transform) {}
-
- bool particles_get_emitting(RID p_particles) { return false; }
- int particles_get_draw_passes(RID p_particles) const { return 0; }
- RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { return RID(); }
+ RID particles_create() override { return RID(); }
+
+ void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {}
+ void particles_set_emitting(RID p_particles, bool p_emitting) override {}
+ void particles_set_amount(RID p_particles, int p_amount) override {}
+ void particles_set_lifetime(RID p_particles, float p_lifetime) override {}
+ void particles_set_one_shot(RID p_particles, bool p_one_shot) override {}
+ void particles_set_pre_process_time(RID p_particles, float p_time) override {}
+ void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) override {}
+ void particles_set_randomness_ratio(RID p_particles, float p_ratio) override {}
+ void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) override {}
+ void particles_set_speed_scale(RID p_particles, float p_scale) override {}
+ void particles_set_use_local_coordinates(RID p_particles, bool p_enable) override {}
+ void particles_set_process_material(RID p_particles, RID p_material) override {}
+ void particles_set_fixed_fps(RID p_particles, int p_fps) override {}
+ void particles_set_fractional_delta(RID p_particles, bool p_enable) override {}
+ void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) override {}
+ void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) override {}
+ void particles_restart(RID p_particles) override {}
+
+ void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) override {}
+
+ void particles_set_draw_passes(RID p_particles, int p_count) override {}
+ void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) override {}
+
+ void particles_request_process(RID p_particles) override {}
+ AABB particles_get_current_aabb(RID p_particles) override { return AABB(); }
+ AABB particles_get_aabb(RID p_particles) const override { return AABB(); }
+
+ void particles_set_emission_transform(RID p_particles, const Transform &p_transform) override {}
+
+ bool particles_get_emitting(RID p_particles) override { return false; }
+ int particles_get_draw_passes(RID p_particles) const override { return 0; }
+ RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override { return RID(); }
/* GLOBAL VARIABLES */
- virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {}
- virtual void global_variable_remove(const StringName &p_name) {}
- virtual Vector<StringName> global_variable_get_list() const { return Vector<StringName>(); }
+ void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {}
+ void global_variable_remove(const StringName &p_name) override {}
+ Vector<StringName> global_variable_get_list() const override { return Vector<StringName>(); }
- virtual void global_variable_set(const StringName &p_name, const Variant &p_value) {}
- virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) {}
- virtual Variant global_variable_get(const StringName &p_name) const { return Variant(); }
- virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const { return RS::GLOBAL_VAR_TYPE_MAX; }
+ void global_variable_set(const StringName &p_name, const Variant &p_value) override {}
+ void global_variable_set_override(const StringName &p_name, const Variant &p_value) override {}
+ Variant global_variable_get(const StringName &p_name) const override { return Variant(); }
+ RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; }
- virtual void global_variables_load_settings(bool p_load_textures = true) {}
- virtual void global_variables_clear() {}
+ void global_variables_load_settings(bool p_load_textures = true) override {}
+ void global_variables_clear() override {}
- virtual int32_t global_variables_instance_allocate(RID p_instance) { return 0; }
- virtual void global_variables_instance_free(RID p_instance) {}
- virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {}
+ int32_t global_variables_instance_allocate(RID p_instance) override { return 0; }
+ void global_variables_instance_free(RID p_instance) override {}
+ void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override {}
- virtual bool particles_is_inactive(RID p_particles) const { return false; }
+ bool particles_is_inactive(RID p_particles) const override { return false; }
/* RENDER TARGET */
- RID render_target_create() { return RID(); }
- void render_target_set_position(RID p_render_target, int p_x, int p_y) {}
- void render_target_set_size(RID p_render_target, int p_width, int p_height) {}
- RID render_target_get_texture(RID p_render_target) { return RID(); }
- void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {}
- void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {}
- bool render_target_was_used(RID p_render_target) { return false; }
- void render_target_set_as_unused(RID p_render_target) {}
-
- virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) {}
- virtual bool render_target_is_clear_requested(RID p_render_target) { return false; }
- virtual Color render_target_get_clear_request_color(RID p_render_target) { return Color(); }
- virtual void render_target_disable_clear_request(RID p_render_target) {}
- virtual void render_target_do_clear_request(RID p_render_target) {}
-
- RS::InstanceType get_base_type(RID p_rid) const {
+ RID render_target_create() override { return RID(); }
+ void render_target_set_position(RID p_render_target, int p_x, int p_y) override {}
+ void render_target_set_size(RID p_render_target, int p_width, int p_height) override {}
+ RID render_target_get_texture(RID p_render_target) override { return RID(); }
+ void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override {}
+ void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override {}
+ bool render_target_was_used(RID p_render_target) override { return false; }
+ void render_target_set_as_unused(RID p_render_target) override {}
+
+ void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {}
+ bool render_target_is_clear_requested(RID p_render_target) override { return false; }
+ Color render_target_get_clear_request_color(RID p_render_target) override { return Color(); }
+ void render_target_disable_clear_request(RID p_render_target) override {}
+ void render_target_do_clear_request(RID p_render_target) override {}
+
+ RS::InstanceType get_base_type(RID p_rid) const override {
if (mesh_owner.owns(p_rid)) {
return RS::INSTANCE_MESH;
}
@@ -875,7 +864,7 @@ public:
return RS::INSTANCE_NONE;
}
- bool free(RID p_rid) {
+ bool free(RID p_rid) override {
if (texture_owner.owns(p_rid)) {
// delete the texture
DummyTexture *texture = texture_owner.getornull(p_rid);
@@ -892,29 +881,29 @@ public:
return true;
}
- bool has_os_feature(const String &p_feature) const { return false; }
+ bool has_os_feature(const String &p_feature) const override { return false; }
- void update_dirty_resources() {}
+ void update_dirty_resources() override {}
- void set_debug_generate_wireframes(bool p_generate) {}
+ void set_debug_generate_wireframes(bool p_generate) override {}
- void render_info_begin_capture() {}
- void render_info_end_capture() {}
- int get_captured_render_info(RS::RenderInfo p_info) { return 0; }
+ void render_info_begin_capture() override {}
+ void render_info_end_capture() override {}
+ int get_captured_render_info(RS::RenderInfo p_info) override { return 0; }
- int get_render_info(RS::RenderInfo p_info) { return 0; }
- String get_video_adapter_name() const { return String(); }
- String get_video_adapter_vendor() const { return String(); }
+ int get_render_info(RS::RenderInfo p_info) override { return 0; }
+ String get_video_adapter_name() const override { return String(); }
+ String get_video_adapter_vendor() const override { return String(); }
static RasterizerStorage *base_singleton;
- virtual void capture_timestamps_begin() {}
- virtual void capture_timestamp(const String &p_name) {}
- virtual uint32_t get_captured_timestamps_count() const { return 0; }
- virtual uint64_t get_captured_timestamps_frame() const { return 0; }
- virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const { return 0; }
- virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const { return 0; }
- virtual String get_captured_timestamp_name(uint32_t p_index) const { return String(); }
+ void capture_timestamps_begin() override {}
+ void capture_timestamp(const String &p_name) override {}
+ uint32_t get_captured_timestamps_count() const override { return 0; }
+ uint64_t get_captured_timestamps_frame() const override { return 0; }
+ uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { return 0; }
+ uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { return 0; }
+ String get_captured_timestamp_name(uint32_t p_index) const override { return String(); }
RasterizerStorageDummy() {}
~RasterizerStorageDummy() {}
@@ -922,28 +911,28 @@ public:
class RasterizerCanvasDummy : public RasterizerCanvas {
public:
- virtual TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { return 0; }
- virtual void free_texture_binding(TextureBindingID p_binding) {}
+ TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) override { return 0; }
+ void free_texture_binding(TextureBindingID p_binding) override {}
- virtual PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) { return 0; }
- virtual void free_polygon(PolygonID p_polygon) {}
+ PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; }
+ void free_polygon(PolygonID p_polygon) override {}
- virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {}
- virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
+ void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) override {}
+ void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {}
- virtual RID light_create() { return RID(); }
- virtual void light_set_texture(RID p_rid, RID p_texture) {}
- virtual void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) {}
- virtual void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {}
+ RID light_create() override { return RID(); }
+ void light_set_texture(RID p_rid, RID p_texture) override {}
+ void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) override {}
+ void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {}
- virtual RID occluder_polygon_create() { return RID(); }
- virtual void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) {}
- virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {}
+ RID occluder_polygon_create() override { return RID(); }
+ void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) override {}
+ void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override {}
- void draw_window_margins(int *p_margins, RID *p_margin_textures) {}
+ void draw_window_margins(int *p_margins, RID *p_margin_textures) override {}
- virtual bool free(RID p_rid) { return true; }
- virtual void update() {}
+ bool free(RID p_rid) override { return true; }
+ void update() override {}
RasterizerCanvasDummy() {}
~RasterizerCanvasDummy() {}
@@ -960,32 +949,28 @@ protected:
RasterizerSceneDummy scene;
public:
- RasterizerStorage *get_storage() { return &storage; }
- RasterizerCanvas *get_canvas() { return &canvas; }
- RasterizerScene *get_scene() { return &scene; }
+ RasterizerStorage *get_storage() override { return &storage; }
+ RasterizerCanvas *get_canvas() override { return &canvas; }
+ RasterizerScene *get_scene() override { return &scene; }
- void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) {}
+ void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override {}
- void initialize() {}
- void begin_frame(double frame_step) {
+ void initialize() override {}
+ void begin_frame(double frame_step) override {
frame++;
delta = frame_step;
}
- virtual void prepare_for_blitting_render_targets() {}
- virtual void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) {}
+ void prepare_for_blitting_render_targets() override {}
+ void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) override {}
- void end_frame(bool p_swap_buffers) {
+ void end_frame(bool p_swap_buffers) override {
if (p_swap_buffers) {
DisplayServer::get_singleton()->swap_buffers();
}
}
- void finalize() {}
-
- static Error is_viable() {
- return OK;
- }
+ void finalize() override {}
static Rasterizer *_create_current() {
return memnew(RasterizerDummy);
@@ -995,9 +980,9 @@ public:
_create_func = _create_current;
}
- virtual bool is_low_end() const { return true; }
- virtual uint64_t get_frame_number() const { return frame; }
- virtual float get_frame_delta_time() const { return delta; }
+ bool is_low_end() const override { return true; }
+ uint64_t get_frame_number() const override { return frame; }
+ float get_frame_delta_time() const override { return delta; }
RasterizerDummy() {}
~RasterizerDummy() {}
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 2f2ad0fc38..35ccae94b8 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef PULSEAUDIO_ENABLED
-
#ifndef AUDIO_DRIVER_PULSEAUDIO_H
#define AUDIO_DRIVER_PULSEAUDIO_H
+#ifdef PULSEAUDIO_ENABLED
+
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "servers/audio_server.h"
@@ -124,6 +124,6 @@ public:
~AudioDriverPulseAudio() {}
};
-#endif // AUDIO_DRIVER_PULSEAUDIO_H
-
#endif // PULSEAUDIO_ENABLED
+
+#endif // AUDIO_DRIVER_PULSEAUDIO_H
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 06bad9f385..51c657007c 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -78,7 +78,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
path_src = p_path;
path = fix_path(p_path);
- //printf("opening %ls, %i\n", path.c_str(), Memory::get_static_mem_usage());
+ //printf("opening %s, %i\n", path.utf8().get_data(), Memory::get_static_mem_usage());
ERR_FAIL_COND_V_MSG(f, ERR_ALREADY_IN_USE, "File is already in use.");
const char *mode_string;
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 3c212cadb8..96c338f86b 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -48,7 +48,7 @@
#include <mach/mach_time.h>
#endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#endif
@@ -171,52 +171,53 @@ double OS_Unix::get_unix_time() const {
OS::Date OS_Unix::get_date(bool utc) const {
time_t t = time(nullptr);
- struct tm *lt;
+ struct tm lt;
if (utc) {
- lt = gmtime(&t);
+ gmtime_r(&t, &lt);
} else {
- lt = localtime(&t);
+ localtime_r(&t, &lt);
}
Date ret;
- ret.year = 1900 + lt->tm_year;
+ ret.year = 1900 + lt.tm_year;
// Index starting at 1 to match OS_Unix::get_date
// and Windows SYSTEMTIME and tm_mon follows the typical structure
// of 0-11, noted here: http://www.cplusplus.com/reference/ctime/tm/
- ret.month = (Month)(lt->tm_mon + 1);
- ret.day = lt->tm_mday;
- ret.weekday = (Weekday)lt->tm_wday;
- ret.dst = lt->tm_isdst;
+ ret.month = (Month)(lt.tm_mon + 1);
+ ret.day = lt.tm_mday;
+ ret.weekday = (Weekday)lt.tm_wday;
+ ret.dst = lt.tm_isdst;
return ret;
}
OS::Time OS_Unix::get_time(bool utc) const {
time_t t = time(nullptr);
- struct tm *lt;
+ struct tm lt;
if (utc) {
- lt = gmtime(&t);
+ gmtime_r(&t, &lt);
} else {
- lt = localtime(&t);
+ localtime_r(&t, &lt);
}
Time ret;
- ret.hour = lt->tm_hour;
- ret.min = lt->tm_min;
- ret.sec = lt->tm_sec;
+ ret.hour = lt.tm_hour;
+ ret.min = lt.tm_min;
+ ret.sec = lt.tm_sec;
get_time_zone_info();
return ret;
}
OS::TimeZoneInfo OS_Unix::get_time_zone_info() const {
time_t t = time(nullptr);
- struct tm *lt = localtime(&t);
+ struct tm lt;
+ localtime_r(&t, &lt);
char name[16];
- strftime(name, 16, "%Z", lt);
+ strftime(name, 16, "%Z", &lt);
name[15] = 0;
TimeZoneInfo ret;
ret.name = name;
char bias_buf[16];
- strftime(bias_buf, 16, "%z", lt);
+ strftime(bias_buf, 16, "%z", &lt);
int bias;
bias_buf[15] = 0;
sscanf(bias_buf, "%d", &bias);
@@ -476,7 +477,7 @@ String OS_Unix::get_executable_path() const {
return OS::get_executable_path();
}
return b;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
char resolved_path[MAXPATHLEN];
realpath(OS::get_executable_path().utf8().get_data(), resolved_path);
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index aa1b5019ca..285088342b 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -29,17 +29,17 @@
/*************************************************************************/
#include "thread_posix.h"
-#include "core/script_language.h"
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
+#include "core/os/memory.h"
+#include "core/safe_refcount.h"
+#include "core/script_language.h"
+
#ifdef PTHREAD_BSD_SET_NAME
#include <pthread_np.h>
#endif
-#include "core/os/memory.h"
-#include "core/safe_refcount.h"
-
static void _thread_id_key_destr_callback(void *p_value) {
memdelete(static_cast<Thread::ID *>(p_value));
}
@@ -126,6 +126,8 @@ Error ThreadPosix::set_name_func_posix(const String &p_name) {
#ifdef PTHREAD_BSD_SET_NAME
pthread_set_name_np(running_thread, p_name.utf8().get_data());
int err = 0; // Open/FreeBSD ignore errors in this function
+#elif defined(PTHREAD_NETBSD_SET_NAME)
+ int err = pthread_setname_np(running_thread, "%s", const_cast<char *>(p_name.utf8().get_data()));
#else
int err = pthread_setname_np(running_thread, p_name.utf8().get_data());
#endif // PTHREAD_BSD_SET_NAME
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index fb890491a4..9fe3f7e6c0 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -3650,7 +3650,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
//print_line("DEBUG: SAMPLER: texel buffer");
} else {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' is of unsupported buffer type.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported buffer type.";
}
return false;
}
@@ -3673,7 +3673,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
} else {
//print_line("DEBUG: sampler unknown");
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' is of unsupported sampler type.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported sampler type.";
}
return false;
}
@@ -3698,7 +3698,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
if (reflection.getType()->getQualifier().layoutPushConstant) {
uint32_t len = reflection.size;
if (push_constant.push_constant_size != 0 && push_constant.push_constant_size != len) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' push constants for different stages should all be the same size.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' push constants for different stages should all be the same size.";
return false;
}
push_constant.push_constant_size = len;
@@ -3714,7 +3714,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
//print_line("DEBUG: Storage buffer");
} else {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' is of unsupported block type: (" + itos(reflection.getType()->getQualifier().storage) + ").";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' is of unsupported block type: (" + itos(reflection.getType()->getQualifier().storage) + ").";
}
return false;
}
@@ -3743,7 +3743,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
}
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' unsupported uniform type.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' unsupported uniform type.";
}
return false;
}
@@ -3751,7 +3751,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
if (!reflection.getType()->getQualifier().hasBinding()) {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' lacks a binding number.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' lacks a binding number.";
}
return false;
}
@@ -3760,14 +3760,14 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
if (set >= MAX_UNIFORM_SETS) {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").";
}
return false;
}
if (set >= limits.maxBoundDescriptorSets) {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' uses a set (" + itos(set) + ") index larger than what is supported by the hardware (" + itos(limits.maxBoundDescriptorSets) + ").";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' uses a set (" + itos(set) + ") index larger than what is supported by the hardware (" + itos(limits.maxBoundDescriptorSets) + ").";
}
return false;
}
@@ -3781,7 +3781,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
//already exists, verify that it's the same type
if (bindings[set][i].descriptorType != layout_binding.descriptorType) {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform type.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform type.";
}
return false;
}
@@ -3789,7 +3789,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
//also, verify that it's the same size
if (bindings[set][i].descriptorCount != layout_binding.descriptorCount || uniform_infos[set][i].length != info.length) {
if (r_error) {
- *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name.c_str() + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform size.";
+ *r_error = "On shader stage '" + String(shader_stage_names[p_stage]) + "', uniform '" + reflection.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(binding) + " with different uniform size.";
}
return false;
}
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index b8153907a9..03e4e30797 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -65,7 +65,7 @@ Error DirAccessWindows::list_dir_begin() {
_cishidden = false;
list_dir_end();
- p->h = FindFirstFileExW((current_dir + "\\*").c_str(), FindExInfoStandard, &p->fu, FindExSearchNameMatch, nullptr, 0);
+ p->h = FindFirstFileExW((LPCWSTR)(String(current_dir + "\\*").utf16().get_data()), FindExInfoStandard, &p->fu, FindExSearchNameMatch, nullptr, 0);
if (p->h == INVALID_HANDLE_VALUE) {
return ERR_CANT_OPEN;
@@ -75,13 +75,14 @@ Error DirAccessWindows::list_dir_begin() {
}
String DirAccessWindows::get_next() {
- if (p->h == INVALID_HANDLE_VALUE)
+ if (p->h == INVALID_HANDLE_VALUE) {
return "";
+ }
_cisdir = (p->fu.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
_cishidden = (p->fu.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
- String name = p->fu.cFileName;
+ String name = String::utf16((const char16_t *)(p->fu.cFileName));
if (FindNextFileW(p->h, &p->fu) == 0) {
FindClose(p->h);
@@ -111,8 +112,9 @@ int DirAccessWindows::get_drive_count() {
}
String DirAccessWindows::get_drive(int p_drive) {
- if (p_drive < 0 || p_drive >= drive_count)
+ if (p_drive < 0 || p_drive >= drive_count) {
return "";
+ }
return String::chr(drives[p_drive]) + ":";
}
@@ -122,18 +124,17 @@ Error DirAccessWindows::change_dir(String p_dir) {
p_dir = fix_path(p_dir);
- wchar_t real_current_dir_name[2048];
+ WCHAR real_current_dir_name[2048];
GetCurrentDirectoryW(2048, real_current_dir_name);
- String prev_dir = real_current_dir_name;
+ String prev_dir = String::utf16((const char16_t *)real_current_dir_name);
- SetCurrentDirectoryW(current_dir.c_str());
- bool worked = (SetCurrentDirectoryW(p_dir.c_str()) != 0);
+ SetCurrentDirectoryW((LPCWSTR)(current_dir.utf16().get_data()));
+ bool worked = (SetCurrentDirectoryW((LPCWSTR)(p_dir.utf16().get_data())) != 0);
String base = _get_root_path();
if (base != "") {
GetCurrentDirectoryW(2048, real_current_dir_name);
- String new_dir;
- new_dir = String(real_current_dir_name).replace("\\", "/");
+ String new_dir = String::utf16((const char16_t *)real_current_dir_name).replace("\\", "/");
if (!new_dir.begins_with(base)) {
worked = false;
}
@@ -141,13 +142,11 @@ Error DirAccessWindows::change_dir(String p_dir) {
if (worked) {
GetCurrentDirectoryW(2048, real_current_dir_name);
- current_dir = real_current_dir_name; // TODO, utf8 parser
+ current_dir = String::utf16((const char16_t *)real_current_dir_name);
current_dir = current_dir.replace("\\", "/");
+ }
- } //else {
-
- SetCurrentDirectoryW(prev_dir.c_str());
- //}
+ SetCurrentDirectoryW((LPCWSTR)(prev_dir.utf16().get_data()));
return worked ? OK : ERR_INVALID_PARAMETER;
}
@@ -156,8 +155,9 @@ Error DirAccessWindows::make_dir(String p_dir) {
GLOBAL_LOCK_FUNCTION
p_dir = fix_path(p_dir);
- if (p_dir.is_rel_path())
+ if (p_dir.is_rel_path()) {
p_dir = current_dir.plus_file(p_dir);
+ }
p_dir = p_dir.replace("/", "\\");
@@ -167,16 +167,16 @@ Error DirAccessWindows::make_dir(String p_dir) {
p_dir = "\\\\?\\" + p_dir; //done according to
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
- success = CreateDirectoryW(p_dir.c_str(), nullptr);
+ success = CreateDirectoryW((LPCWSTR)(p_dir.utf16().get_data()), nullptr);
err = GetLastError();
if (success) {
return OK;
- };
+ }
if (err == ERROR_ALREADY_EXISTS || err == ERROR_ACCESS_DENIED) {
return ERR_ALREADY_EXISTS;
- };
+ }
return ERR_CANT_CREATE;
}
@@ -185,12 +185,11 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) {
String base = _get_root_path();
if (base != "") {
String bd = current_dir.replace("\\", "/").replace_first(base, "");
- if (bd.begins_with("/"))
+ if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
- else
+ } else {
return _get_root_string() + bd;
-
- } else {
+ }
}
if (p_include_drive) {
@@ -209,20 +208,18 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) {
bool DirAccessWindows::file_exists(String p_file) {
GLOBAL_LOCK_FUNCTION
- if (!p_file.is_abs_path())
+ if (!p_file.is_abs_path()) {
p_file = get_current_dir().plus_file(p_file);
+ }
p_file = fix_path(p_file);
- //p_file.replace("/","\\");
-
- //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
-
DWORD fileAttr;
- fileAttr = GetFileAttributesW(p_file.c_str());
- if (INVALID_FILE_ATTRIBUTES == fileAttr)
+ fileAttr = GetFileAttributesW((LPCWSTR)(p_file.utf16().get_data()));
+ if (INVALID_FILE_ATTRIBUTES == fileAttr) {
return false;
+ }
return !(fileAttr & FILE_ATTRIBUTE_DIRECTORY);
}
@@ -230,31 +227,30 @@ bool DirAccessWindows::file_exists(String p_file) {
bool DirAccessWindows::dir_exists(String p_dir) {
GLOBAL_LOCK_FUNCTION
- if (p_dir.is_rel_path())
+ if (p_dir.is_rel_path()) {
p_dir = get_current_dir().plus_file(p_dir);
+ }
p_dir = fix_path(p_dir);
- //p_dir.replace("/","\\");
-
- //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
-
DWORD fileAttr;
-
- fileAttr = GetFileAttributesW(p_dir.c_str());
- if (INVALID_FILE_ATTRIBUTES == fileAttr)
+ fileAttr = GetFileAttributesW((LPCWSTR)(p_dir.utf16().get_data()));
+ if (INVALID_FILE_ATTRIBUTES == fileAttr) {
return false;
+ }
return (fileAttr & FILE_ATTRIBUTE_DIRECTORY);
}
Error DirAccessWindows::rename(String p_path, String p_new_path) {
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
p_path = get_current_dir().plus_file(p_path);
+ }
p_path = fix_path(p_path);
- if (p_new_path.is_rel_path())
+ if (p_new_path.is_rel_path()) {
p_new_path = get_current_dir().plus_file(p_new_path);
+ }
p_new_path = fix_path(p_new_path);
@@ -262,16 +258,16 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) {
if (p_path.to_lower() == p_new_path.to_lower()) {
WCHAR tmpfile[MAX_PATH];
- if (!GetTempFileNameW(fix_path(get_current_dir()).c_str(), nullptr, 0, tmpfile)) {
+ if (!GetTempFileNameW((LPCWSTR)(fix_path(get_current_dir()).utf16().get_data()), nullptr, 0, tmpfile)) {
return FAILED;
}
- if (!::ReplaceFileW(tmpfile, p_path.c_str(), nullptr, 0, nullptr, nullptr)) {
+ if (!::ReplaceFileW(tmpfile, (LPCWSTR)(p_path.utf16().get_data()), nullptr, 0, nullptr, nullptr)) {
DeleteFileW(tmpfile);
return FAILED;
}
- return ::_wrename(tmpfile, p_new_path.c_str()) == 0 ? OK : FAILED;
+ return ::_wrename(tmpfile, (LPCWSTR)(p_new_path.utf16().get_data())) == 0 ? OK : FAILED;
} else {
if (file_exists(p_new_path)) {
@@ -280,60 +276,60 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) {
}
}
- return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED;
+ return ::_wrename((LPCWSTR)(p_path.utf16().get_data()), (LPCWSTR)(p_new_path.utf16().get_data())) == 0 ? OK : FAILED;
}
}
Error DirAccessWindows::remove(String p_path) {
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
p_path = get_current_dir().plus_file(p_path);
+ }
p_path = fix_path(p_path);
DWORD fileAttr;
- fileAttr = GetFileAttributesW(p_path.c_str());
- if (INVALID_FILE_ATTRIBUTES == fileAttr)
+ fileAttr = GetFileAttributesW((LPCWSTR)(p_path.utf16().get_data()));
+ if (INVALID_FILE_ATTRIBUTES == fileAttr) {
return FAILED;
- if ((fileAttr & FILE_ATTRIBUTE_DIRECTORY))
- return ::_wrmdir(p_path.c_str()) == 0 ? OK : FAILED;
- else
- return ::_wunlink(p_path.c_str()) == 0 ? OK : FAILED;
+ }
+ if ((fileAttr & FILE_ATTRIBUTE_DIRECTORY)) {
+ return ::_wrmdir((LPCWSTR)(p_path.utf16().get_data())) == 0 ? OK : FAILED;
+ } else {
+ return ::_wunlink((LPCWSTR)(p_path.utf16().get_data())) == 0 ? OK : FAILED;
+ }
}
/*
FileType DirAccessWindows::get_file_type(const String& p_file) const {
+ WCHAR real_current_dir_name[2048];
+ GetCurrentDirectoryW(2048, real_current_dir_name);
+ String prev_dir = Strong::utf16((const char16_t *)real_current_dir_name);
-
- wchar_t real_current_dir_name[2048];
- GetCurrentDirectoryW(2048,real_current_dir_name);
- String prev_dir=real_current_dir_name;
-
- bool worked SetCurrentDirectoryW(current_dir.c_str());
+ bool worked = SetCurrentDirectoryW((LPCWSTR)(current_dir.utf16().get_data()));
DWORD attr;
if (worked) {
-
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
- attr = GetFileAttributesExW(p_file.c_str(), GetFileExInfoStandard, &fileInfo);
-
+ WIN32_FILE_ATTRIBUTE_DATA fileInfo;
+ attr = GetFileAttributesExW((LPCWSTR)(p_file.utf16().get_data()), GetFileExInfoStandard, &fileInfo);
}
- SetCurrentDirectoryW(prev_dir.c_str());
+ SetCurrentDirectoryW((LPCWSTR)(prev_dir.utf16().get_data()));
- if (!worked)
+ if (!worked) {
return FILE_TYPE_NONE;
+ }
-
- return (attr&FILE_ATTRIBUTE_DIRECTORY)?FILE_TYPE_
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FILE_TYPE_
}
*/
size_t DirAccessWindows::get_space_left() {
uint64_t bytes = 0;
- if (!GetDiskFreeSpaceEx(nullptr, (PULARGE_INTEGER)&bytes, nullptr, nullptr))
+ if (!GetDiskFreeSpaceEx(nullptr, (PULARGE_INTEGER)&bytes, nullptr, nullptr)) {
return 0;
+ }
//this is either 0 or a value in bytes.
return (size_t)bytes;
@@ -352,7 +348,7 @@ String DirAccessWindows::get_filesystem_type() const {
DWORD dwMaxFileNameLength = 0;
DWORD dwFileSystemFlags = 0;
- if (::GetVolumeInformationW(unit.c_str(),
+ if (::GetVolumeInformationW((LPCWSTR)(unit.utf16().get_data()),
szVolumeName,
sizeof(szVolumeName),
&dwSerialNumber,
@@ -360,7 +356,7 @@ String DirAccessWindows::get_filesystem_type() const {
&dwFileSystemFlags,
szFileSystemName,
sizeof(szFileSystemName)) == TRUE) {
- return String(szFileSystemName);
+ return String::utf16((const char16_t *)szFileSystemName);
}
ERR_FAIL_V("");
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 50366d0b2d..dd86061ea7 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -59,29 +59,32 @@ void FileAccessWindows::check_errors() const {
Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
path_src = p_path;
path = fix_path(p_path);
- if (f)
+ if (f) {
close();
+ }
- const wchar_t *mode_string;
+ const WCHAR *mode_string;
- if (p_mode_flags == READ)
+ if (p_mode_flags == READ) {
mode_string = L"rb";
- else if (p_mode_flags == WRITE)
+ } else if (p_mode_flags == WRITE) {
mode_string = L"wb";
- else if (p_mode_flags == READ_WRITE)
+ } else if (p_mode_flags == READ_WRITE) {
mode_string = L"rb+";
- else if (p_mode_flags == WRITE_READ)
+ } else if (p_mode_flags == WRITE_READ) {
mode_string = L"wb+";
- else
+ } else {
return ERR_INVALID_PARAMETER;
+ }
/* pretty much every implementation that uses fopen as primary
backend supports utf8 encoding */
struct _stat st;
- if (_wstat(path.c_str(), &st) == 0) {
- if (!S_ISREG(st.st_mode))
+ if (_wstat((LPCWSTR)(path.utf16().get_data()), &st) == 0) {
+ if (!S_ISREG(st.st_mode)) {
return ERR_FILE_CANT_OPEN;
+ }
};
#ifdef TOOLS_ENABLED
@@ -91,9 +94,9 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
// platforms).
if (p_mode_flags == READ) {
WIN32_FIND_DATAW d;
- HANDLE f = FindFirstFileW(path.c_str(), &d);
+ HANDLE f = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d);
if (f != INVALID_HANDLE_VALUE) {
- String fname = d.cFileName;
+ String fname = String::utf16((const char16_t *)(d.cFileName));
if (fname != String()) {
String base_file = path.get_file();
if (base_file != fname && base_file.findn(fname) == 0) {
@@ -110,7 +113,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
path = path + ".tmp";
}
- errno_t errcode = _wfopen_s(&f, path.c_str(), mode_string);
+ errno_t errcode = _wfopen_s(&f, (LPCWSTR)(path.utf16().get_data()), mode_string);
if (f == nullptr) {
switch (errcode) {
@@ -130,8 +133,9 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessWindows::close() {
- if (!f)
+ if (!f) {
return;
+ }
fclose(f);
f = nullptr;
@@ -148,16 +152,16 @@ void FileAccessWindows::close() {
// UWP has no PathFileExists, so we check attributes instead
DWORD fileAttr;
- fileAttr = GetFileAttributesW(save_path.c_str());
+ fileAttr = GetFileAttributesW((LPCWSTR)(save_path.utf16().get_data()));
if (INVALID_FILE_ATTRIBUTES == fileAttr) {
#else
- if (!PathFileExistsW(save_path.c_str())) {
+ if (!PathFileExistsW((LPCWSTR)(save_path.utf16().get_data()))) {
#endif
//creating new file
- rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0;
+ rename_error = _wrename((LPCWSTR)((save_path + ".tmp").utf16().get_data()), (LPCWSTR)(save_path.utf16().get_data())) != 0;
} else {
//atomic replace for existing file
- rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), nullptr, 2 | 4, nullptr, nullptr);
+ rename_error = !ReplaceFileW((LPCWSTR)(save_path.utf16().get_data()), (LPCWSTR)((save_path + ".tmp").utf16().get_data()), nullptr, 2 | 4, nullptr, nullptr);
}
if (rename_error) {
attempts--;
@@ -192,15 +196,17 @@ bool FileAccessWindows::is_open() const {
void FileAccessWindows::seek(size_t p_position) {
ERR_FAIL_COND(!f);
last_error = OK;
- if (fseek(f, p_position, SEEK_SET))
+ if (fseek(f, p_position, SEEK_SET)) {
check_errors();
+ }
prev_op = 0;
}
void FileAccessWindows::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);
- if (fseek(f, p_position, SEEK_END))
+ if (fseek(f, p_position, SEEK_END)) {
check_errors();
+ }
prev_op = 0;
}
@@ -209,7 +215,7 @@ size_t FileAccessWindows::get_position() const {
aux_position = ftell(f);
if (!aux_position) {
check_errors();
- };
+ }
return aux_position;
}
@@ -241,7 +247,7 @@ uint8_t FileAccessWindows::get_8() const {
if (fread(&b, 1, 1, f) == 0) {
check_errors();
b = '\0';
- };
+ }
return b;
}
@@ -266,8 +272,9 @@ Error FileAccessWindows::get_error() const {
void FileAccessWindows::flush() {
ERR_FAIL_COND(!f);
fflush(f);
- if (prev_op == WRITE)
+ if (prev_op == WRITE) {
prev_op = 0;
+ }
}
void FileAccessWindows::store_8(uint8_t p_dest) {
@@ -298,9 +305,9 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) {
bool FileAccessWindows::file_exists(const String &p_name) {
FILE *g;
- //printf("opening file %s\n", p_fname.c_str());
+ //printf("opening file %s\n", p_fname.utf8().get_data());
String filename = fix_path(p_name);
- _wfopen_s(&g, filename.c_str(), L"rb");
+ _wfopen_s(&g, (LPCWSTR)(filename.utf16().get_data()), L"rb");
if (g == nullptr) {
return false;
} else {
@@ -315,7 +322,7 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
file = file.substr(0, file.length() - 1);
struct _stat st;
- int rv = _wstat(file.c_str(), &st);
+ int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st);
if (rv == 0) {
return st.st_mtime;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 37db3ba780..ede6dde239 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -40,7 +40,7 @@
#include "scene/gui/separator.h"
#include "scene/resources/dynamic_font.h"
-void GotoLineDialog::popup_find_line(TextEdit *p_edit) {
+void GotoLineDialog::popup_find_line(CodeEdit *p_edit) {
text_editor = p_edit;
line->set_text(itos(text_editor->cursor_get_line()));
@@ -113,7 +113,7 @@ void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
}
Control *focus_owner = get_focus_owner();
- if (text_edit->has_focus() || (focus_owner && vbc_lineedit->is_a_parent_of(focus_owner))) {
+ if (text_editor->has_focus() || (focus_owner && vbc_lineedit->is_a_parent_of(focus_owner))) {
bool accepted = true;
switch (k->get_keycode()) {
@@ -135,20 +135,20 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
int line, col;
String text = get_search_text();
- bool found = text_edit->search(text, p_flags, p_from_line, p_from_col, line, col);
+ bool found = text_editor->search(text, p_flags, p_from_line, p_from_col, line, col);
if (found) {
if (!preserve_cursor) {
- text_edit->unfold_line(line);
- 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_editor->unfold_line(line);
+ text_editor->cursor_set_line(line, false);
+ text_editor->cursor_set_column(col + text.length(), false);
+ text_editor->center_viewport_to_cursor();
+ text_editor->select(line, col, line, col + text.length());
}
- text_edit->set_search_text(text);
- text_edit->set_search_flags(p_flags);
- text_edit->set_current_search_result(line, col);
+ text_editor->set_search_text(text);
+ text_editor->set_search_flags(p_flags);
+ text_editor->set_current_search_result(line, col);
result_line = line;
result_col = col;
@@ -158,9 +158,9 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
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);
+ text_editor->set_search_text("");
+ text_editor->set_search_flags(p_flags);
+ text_editor->set_current_search_result(line, col);
}
_update_matches_label();
@@ -169,67 +169,67 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
}
void FindReplaceBar::_replace() {
- bool selection_enabled = text_edit->is_selection_active();
+ bool selection_enabled = text_editor->is_selection_active();
Point2i selection_begin, selection_end;
if (selection_enabled) {
- selection_begin = Point2i(text_edit->get_selection_from_line(), text_edit->get_selection_from_column());
- selection_end = Point2i(text_edit->get_selection_to_line(), text_edit->get_selection_to_column());
+ selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column());
+ selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column());
}
String replace_text = get_replace_text();
int search_text_len = get_search_text().length();
- text_edit->begin_complex_operation();
+ text_editor->begin_complex_operation();
if (selection_enabled && is_selection_only()) { // To restrict search_current() to selected region
- text_edit->cursor_set_line(selection_begin.width);
- text_edit->cursor_set_column(selection_begin.height);
+ text_editor->cursor_set_line(selection_begin.width);
+ text_editor->cursor_set_column(selection_begin.height);
}
if (search_current()) {
- text_edit->unfold_line(result_line);
- text_edit->select(result_line, result_col, result_line, result_col + search_text_len);
+ text_editor->unfold_line(result_line);
+ text_editor->select(result_line, result_col, result_line, result_col + search_text_len);
if (selection_enabled && is_selection_only()) {
Point2i match_from(result_line, result_col);
Point2i match_to(result_line, result_col + search_text_len);
if (!(match_from < selection_begin || match_to > selection_end)) {
- text_edit->insert_text_at_cursor(replace_text);
+ text_editor->insert_text_at_cursor(replace_text);
if (match_to.x == selection_end.x) { // Adjust selection bounds if necessary
selection_end.y += replace_text.length() - search_text_len;
}
}
} else {
- text_edit->insert_text_at_cursor(replace_text);
+ text_editor->insert_text_at_cursor(replace_text);
}
}
- text_edit->end_complex_operation();
+ text_editor->end_complex_operation();
results_count = -1;
if (selection_enabled && is_selection_only()) {
// Reselect in order to keep 'Replace' restricted to selection
- text_edit->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
+ text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
} else {
- text_edit->deselect();
+ text_editor->deselect();
}
}
void FindReplaceBar::_replace_all() {
- text_edit->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
+ text_editor->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
// 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 orig_cursor(text_editor->cursor_get_line(), text_editor->cursor_get_column());
Point2i prev_match = Point2(-1, -1);
- bool selection_enabled = text_edit->is_selection_active();
+ bool selection_enabled = text_editor->is_selection_active();
Point2i selection_begin, selection_end;
if (selection_enabled) {
- selection_begin = Point2i(text_edit->get_selection_from_line(), text_edit->get_selection_from_column());
- selection_end = Point2i(text_edit->get_selection_to_line(), text_edit->get_selection_to_column());
+ selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column());
+ selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column());
}
- int vsval = text_edit->get_v_scroll();
+ int vsval = text_editor->get_v_scroll();
- text_edit->cursor_set_line(0);
- text_edit->cursor_set_column(0);
+ text_editor->cursor_set_line(0);
+ text_editor->cursor_set_column(0);
String replace_text = get_replace_text();
int search_text_len = get_search_text().length();
@@ -238,11 +238,11 @@ void FindReplaceBar::_replace_all() {
replace_all_mode = true;
- text_edit->begin_complex_operation();
+ text_editor->begin_complex_operation();
if (selection_enabled && is_selection_only()) {
- text_edit->cursor_set_line(selection_begin.width);
- text_edit->cursor_set_column(selection_begin.height);
+ text_editor->cursor_set_line(selection_begin.width);
+ text_editor->cursor_set_column(selection_begin.height);
}
if (search_current()) {
do {
@@ -256,8 +256,8 @@ void FindReplaceBar::_replace_all() {
prev_match = Point2i(result_line, result_col + replace_text.length());
- text_edit->unfold_line(result_line);
- text_edit->select(result_line, result_col, result_line, match_to.y);
+ text_editor->unfold_line(result_line);
+ text_editor->select(result_line, result_col, result_line, match_to.y);
if (selection_enabled && is_selection_only()) {
if (match_from < selection_begin || match_to > selection_end) {
@@ -265,48 +265,48 @@ void FindReplaceBar::_replace_all() {
}
// Replace but adjust selection bounds.
- text_edit->insert_text_at_cursor(replace_text);
+ text_editor->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.
- text_edit->insert_text_at_cursor(replace_text);
+ text_editor->insert_text_at_cursor(replace_text);
}
rc++;
} while (search_next());
}
- text_edit->end_complex_operation();
+ text_editor->end_complex_operation();
replace_all_mode = false;
// Restore editor state (selection, cursor, scroll).
- text_edit->cursor_set_line(orig_cursor.x);
- text_edit->cursor_set_column(orig_cursor.y);
+ text_editor->cursor_set_line(orig_cursor.x);
+ text_editor->cursor_set_column(orig_cursor.y);
if (selection_enabled && is_selection_only()) {
// Reselect.
- text_edit->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
+ text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
} else {
- text_edit->deselect();
+ text_editor->deselect();
}
- text_edit->set_v_scroll(vsval);
+ text_editor->set_v_scroll(vsval);
matches_label->add_theme_color_override("font_color", rc > 0 ? get_theme_color("font_color", "Label") : get_theme_color("error_color", "Editor"));
matches_label->set_text(vformat(TTR("%d replaced."), rc));
- text_edit->call_deferred("connect", "text_changed", Callable(this, "_editor_text_changed"));
+ text_editor->call_deferred("connect", "text_changed", Callable(this, "_editor_text_changed"));
results_count = -1;
}
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();
+ r_line = text_editor->cursor_get_line();
+ r_col = text_editor->cursor_get_column();
- if (text_edit->is_selection_active() && is_selection_only()) {
+ if (text_editor->is_selection_active() && is_selection_only()) {
return;
}
@@ -327,7 +327,7 @@ void FindReplaceBar::_update_results_count() {
return;
}
- String full_text = text_edit->get_text();
+ String full_text = text_editor->get_text();
int from_pos = 0;
@@ -399,7 +399,7 @@ bool FindReplaceBar::search_prev() {
int line, col;
_get_search_from(line, col);
- if (text_edit->is_selection_active()) {
+ if (text_editor->is_selection_active()) {
col--; // Skip currently selected word.
}
@@ -407,9 +407,9 @@ bool FindReplaceBar::search_prev() {
if (col < 0) {
line -= 1;
if (line < 0) {
- line = text_edit->get_line_count() - 1;
+ line = text_editor->get_line_count() - 1;
}
- col = text_edit->get_line(line).length();
+ col = text_editor->get_line(line).length();
}
return _search(flags, line, col);
@@ -440,9 +440,9 @@ bool FindReplaceBar::search_next() {
if (line == result_line && col == result_col) {
col += text.length();
- if (col > text_edit->get_line(line).length()) {
+ if (col > text_editor->get_line(line).length()) {
line += 1;
- if (line >= text_edit->get_line_count()) {
+ if (line >= text_editor->get_line_count()) {
line = 0;
}
col = 0;
@@ -454,10 +454,10 @@ bool FindReplaceBar::search_next() {
void FindReplaceBar::_hide_bar() {
if (replace_text->has_focus() || search_text->has_focus()) {
- text_edit->grab_focus();
+ text_editor->grab_focus();
}
- text_edit->set_search_text("");
+ text_editor->set_search_text("");
result_line = -1;
result_col = -1;
hide();
@@ -477,8 +477,8 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
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 (text_editor->is_selection_active() && !selection_only->is_pressed()) {
+ search_text->set_text(text_editor->get_selection_text());
}
if (!get_search_text().empty()) {
@@ -511,9 +511,9 @@ void FindReplaceBar::popup_replace() {
hbc_option_replace->show();
}
- selection_only->set_pressed((text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()));
+ selection_only->set_pressed((text_editor->is_selection_active() && text_editor->get_selection_from_line() < text_editor->get_selection_to_line()));
- _show_search(is_visible() || text_edit->is_selection_active());
+ _show_search(is_visible() || text_editor->is_selection_active());
}
void FindReplaceBar::_search_options_changed(bool p_pressed) {
@@ -544,7 +544,7 @@ void FindReplaceBar::_search_text_entered(const String &p_text) {
}
void FindReplaceBar::_replace_text_entered(const String &p_text) {
- if (selection_only->is_pressed() && text_edit->is_selection_active()) {
+ if (selection_only->is_pressed() && text_editor->is_selection_active()) {
_replace_all();
_hide_bar();
} else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
@@ -579,10 +579,10 @@ void FindReplaceBar::set_error(const String &p_label) {
emit_signal("error", p_label);
}
-void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) {
+void FindReplaceBar::set_text_edit(CodeEdit *p_text_edit) {
results_count = -1;
- text_edit = p_text_edit;
- text_edit->connect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
+ text_editor = p_text_edit;
+ text_editor->connect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
}
void FindReplaceBar::_bind_methods() {
@@ -932,11 +932,9 @@ void CodeTextEditor::update_editor_settings() {
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((int)EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width") * EDSCALE);
- text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers"));
+ text_editor->set_draw_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_draw_bookmarks_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/show_bookmark_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"));
@@ -1390,11 +1388,11 @@ void CodeTextEditor::goto_line_centered(int p_line) {
}
void CodeTextEditor::set_executing_line(int p_line) {
- text_editor->set_executing_line(p_line);
+ text_editor->set_line_as_executing(p_line, true);
}
void CodeTextEditor::clear_executing_line() {
- text_editor->clear_executing_line();
+ text_editor->clear_executing_lines();
}
Variant CodeTextEditor::get_edit_state() {
@@ -1405,8 +1403,8 @@ Variant CodeTextEditor::get_edit_state() {
state["column"] = text_editor->cursor_get_column();
state["row"] = text_editor->cursor_get_line();
- state["selection"] = get_text_edit()->is_selection_active();
- if (get_text_edit()->is_selection_active()) {
+ state["selection"] = get_text_editor()->is_selection_active();
+ if (get_text_editor()->is_selection_active()) {
state["selection_from_line"] = text_editor->get_selection_from_line();
state["selection_from_column"] = text_editor->get_selection_from_column();
state["selection_to_line"] = text_editor->get_selection_to_line();
@@ -1414,8 +1412,8 @@ Variant CodeTextEditor::get_edit_state() {
}
state["folded_lines"] = text_editor->get_folded_lines();
- state["breakpoints"] = text_editor->get_breakpoints_array();
- state["bookmarks"] = text_editor->get_bookmarks_array();
+ state["breakpoints"] = text_editor->get_breakpointed_lines();
+ state["bookmarks"] = text_editor->get_bookmarked_lines();
Ref<EditorSyntaxHighlighter> syntax_highlighter = text_editor->get_syntax_highlighter();
state["syntax_highlighter"] = syntax_highlighter->_get_name();
@@ -1453,7 +1451,7 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
if (state.has("bookmarks")) {
Array bookmarks = state["bookmarks"];
for (int i = 0; i < bookmarks.size(); i++) {
- text_editor->set_line_as_bookmark(bookmarks[i], true);
+ text_editor->set_line_as_bookmarked(bookmarks[i], true);
}
}
}
@@ -1591,27 +1589,26 @@ void CodeTextEditor::set_warning_nb(int p_warning_nb) {
void CodeTextEditor::toggle_bookmark() {
int line = text_editor->cursor_get_line();
- text_editor->set_line_as_bookmark(line, !text_editor->is_line_set_as_bookmark(line));
+ text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line));
}
void CodeTextEditor::goto_next_bookmark() {
- List<int> bmarks;
- text_editor->get_bookmarks(&bmarks);
+ Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
int line = text_editor->cursor_get_line();
- if (line >= bmarks[bmarks.size() - 1]) {
+ if (line >= (int)bmarks[bmarks.size() - 1]) {
text_editor->unfold_line(bmarks[0]);
text_editor->cursor_set_line(bmarks[0]);
text_editor->center_viewport_to_cursor();
} else {
- for (List<int>::Element *E = bmarks.front(); E; E = E->next()) {
- int bline = E->get();
- if (bline > line) {
- text_editor->unfold_line(bline);
- text_editor->cursor_set_line(bline);
+ for (int i = 0; i < bmarks.size(); i++) {
+ int bmark_line = bmarks[i];
+ if (bmark_line > line) {
+ text_editor->unfold_line(bmark_line);
+ text_editor->cursor_set_line(bmark_line);
text_editor->center_viewport_to_cursor();
return;
}
@@ -1620,23 +1617,22 @@ void CodeTextEditor::goto_next_bookmark() {
}
void CodeTextEditor::goto_prev_bookmark() {
- List<int> bmarks;
- text_editor->get_bookmarks(&bmarks);
+ Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
int line = text_editor->cursor_get_line();
- if (line <= bmarks[0]) {
+ if (line <= (int)bmarks[0]) {
text_editor->unfold_line(bmarks[bmarks.size() - 1]);
text_editor->cursor_set_line(bmarks[bmarks.size() - 1]);
text_editor->center_viewport_to_cursor();
} else {
- for (List<int>::Element *E = bmarks.back(); E; E = E->prev()) {
- int bline = E->get();
- if (bline < line) {
- text_editor->unfold_line(bline);
- text_editor->cursor_set_line(bline);
+ for (int i = bmarks.size(); i >= 0; i--) {
+ int bmark_line = bmarks[i];
+ if (bmark_line < line) {
+ text_editor->unfold_line(bmark_line);
+ text_editor->cursor_set_line(bmark_line);
text_editor->center_viewport_to_cursor();
return;
}
@@ -1645,12 +1641,7 @@ void CodeTextEditor::goto_prev_bookmark() {
}
void CodeTextEditor::remove_all_bookmarks() {
- List<int> bmarks;
- text_editor->get_bookmarks(&bmarks);
-
- for (List<int>::Element *E = bmarks.front(); E; E = E->next()) {
- text_editor->set_line_as_bookmark(E->get(), false);
- }
+ text_editor->clear_bookmarked_lines();
}
void CodeTextEditor::_bind_methods() {
@@ -1681,7 +1672,7 @@ CodeTextEditor::CodeTextEditor() {
ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KEY_MASK_CMD | KEY_MINUS);
ED_SHORTCUT("script_editor/reset_zoom", TTR("Reset Zoom"), KEY_MASK_CMD | KEY_0);
- text_editor = memnew(TextEdit);
+ text_editor = memnew(CodeEdit);
add_child(text_editor);
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1693,7 +1684,7 @@ CodeTextEditor::CodeTextEditor() {
find_replace_bar->set_text_edit(text_editor);
- text_editor->set_show_line_numbers(true);
+ text_editor->set_draw_line_numbers(true);
text_editor->set_brace_matching(true);
text_editor->set_auto_indent(true);
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 450c85c64b..b38170cbf5 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -34,9 +34,9 @@
#include "editor/editor_plugin.h"
#include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
+#include "scene/gui/code_edit.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
-#include "scene/gui/text_edit.h"
#include "scene/main/timer.h"
class GotoLineDialog : public ConfirmationDialog {
@@ -45,15 +45,15 @@ class GotoLineDialog : public ConfirmationDialog {
Label *line_label;
LineEdit *line;
- TextEdit *text_editor;
+ CodeEdit *text_editor;
virtual void ok_pressed() override;
public:
- void popup_find_line(TextEdit *p_edit);
+ void popup_find_line(CodeEdit *p_edit);
int get_line() const;
- void set_text_editor(TextEdit *p_text_editor);
+ void set_text_editor(CodeEdit *p_text_editor);
GotoLineDialog();
};
@@ -77,7 +77,7 @@ class FindReplaceBar : public HBoxContainer {
HBoxContainer *hbc_button_replace;
HBoxContainer *hbc_option_replace;
- TextEdit *text_edit;
+ CodeEdit *text_editor;
int result_line;
int result_col;
@@ -120,7 +120,7 @@ public:
bool is_selection_only() const;
void set_error(const String &p_label);
- void set_text_edit(TextEdit *p_text_edit);
+ void set_text_edit(CodeEdit *p_text_edit);
void popup_search(bool p_show_only = false);
void popup_replace();
@@ -137,7 +137,7 @@ typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code,
class CodeTextEditor : public VBoxContainer {
GDCLASS(CodeTextEditor, VBoxContainer);
- TextEdit *text_editor;
+ CodeEdit *text_editor;
FindReplaceBar *find_replace_bar;
HBoxContainer *status_bar;
@@ -240,7 +240,7 @@ public:
void set_error(const String &p_error);
void set_error_pos(int p_line, int p_column);
void update_line_and_column() { _line_col_changed(); }
- TextEdit *get_text_edit() { return text_editor; }
+ CodeEdit *get_text_editor() { return text_editor; }
FindReplaceBar *get_find_replace_bar() { return find_replace_bar; }
virtual void apply_code() {}
void goto_error();
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index d3dff3f375..d1661fd7b3 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -714,7 +714,7 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
const String &signalname = signal;
String midname = selectedNode->get_name();
for (int i = 0; i < midname.length(); i++) { //TODO: Regex filter may be cleaner.
- CharType c = midname[i];
+ char32_t c = midname[i];
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) {
if (c == ' ') {
// Replace spaces with underlines.
@@ -754,8 +754,9 @@ void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToE
Node *dst = static_cast<Node *>(cToEdit.target);
if (src && dst) {
+ const String &signalname = cToEdit.signal;
connect_dialog->set_title(TTR("Edit Connection:") + cToEdit.signal);
- connect_dialog->popup_centered();
+ connect_dialog->popup_dialog(signalname);
connect_dialog->init(cToEdit, true);
}
}
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index aae476ccf4..cbde7d593a 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -144,7 +144,10 @@ EditorAbout::EditorAbout() {
List<String> dev_sections;
dev_sections.push_back(TTR("Project Founders"));
dev_sections.push_back(TTR("Lead Developer"));
- dev_sections.push_back(TTR("Project Manager ")); // " " appended to distinguish between 'project supervisor' and 'project list'
+ // TRANSLATORS: This refers to a job title.
+ // The trailing space is used to distinguish with the project list application,
+ // you do not have to keep it in your translation.
+ dev_sections.push_back(TTR("Project Manager "));
dev_sections.push_back(TTR("Developers"));
const char *const *dev_src[] = { AUTHORS_FOUNDERS, AUTHORS_LEAD_DEVELOPERS,
AUTHORS_PROJECT_MANAGERS, AUTHORS_DEVELOPERS };
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index 87c060d1f5..b6cf1183b5 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -230,7 +230,7 @@ private:
render_db_value = n.render_db_value;
}
- _FORCE_INLINE_ AudioNotch operator=(const EditorAudioMeterNotches::AudioNotch &n) {
+ _FORCE_INLINE_ AudioNotch &operator=(const EditorAudioMeterNotches::AudioNotch &n) {
relative_position = n.relative_position;
db_value = n.db_value;
render_db_value = n.render_db_value;
diff --git a/editor/editor_builders.py b/editor/editor_builders.py
index ea32e24f6e..86c5c87a68 100644
--- a/editor/editor_builders.py
+++ b/editor/editor_builders.py
@@ -54,7 +54,6 @@ def make_fonts_header(target, source, env):
g.write("#define _EDITOR_FONTS_H\n")
# saving uncompressed, since freetype will reference from memory pointer
- xl_names = []
for i in range(len(source)):
with open(source[i], "rb") as f:
buf = f.read()
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 130c330f5a..5118ccacad 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -262,7 +262,9 @@ EditorHistory::EditorHistory() {
}
EditorPlugin *EditorData::get_editor(Object *p_object) {
- for (int i = 0; i < editor_plugins.size(); i++) {
+ // We need to iterate backwards so that we can check user-created plugins first.
+ // Otherwise, it would not be possible for plugins to handle CanvasItem and Spatial nodes.
+ for (int i = editor_plugins.size() - 1; i > -1; i--) {
if (editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
return editor_plugins[i];
}
@@ -272,7 +274,7 @@ EditorPlugin *EditorData::get_editor(Object *p_object) {
}
EditorPlugin *EditorData::get_subeditor(Object *p_object) {
- for (int i = 0; i < editor_plugins.size(); i++) {
+ for (int i = editor_plugins.size() - 1; i > -1; i--) {
if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
return editor_plugins[i];
}
@@ -283,7 +285,7 @@ EditorPlugin *EditorData::get_subeditor(Object *p_object) {
Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) {
Vector<EditorPlugin *> sub_plugins;
- for (int i = 0; i < editor_plugins.size(); i++) {
+ for (int i = editor_plugins.size() - 1; i > -1; i--) {
if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
sub_plugins.push_back(editor_plugins[i]);
}
@@ -292,7 +294,7 @@ Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) {
}
EditorPlugin *EditorData::get_editor(String p_name) {
- for (int i = 0; i < editor_plugins.size(); i++) {
+ for (int i = editor_plugins.size() - 1; i > -1; i--) {
if (editor_plugins[i]->get_name() == p_name) {
return editor_plugins[i];
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 16e69734d3..d3a4dbb6e7 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -32,6 +32,7 @@
#include "core/crypto/crypto_core.h"
#include "core/io/config_file.h"
+#include "core/io/file_access_encrypted.h"
#include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
@@ -222,6 +223,42 @@ String EditorExportPreset::get_custom_features() const {
return custom_features;
}
+void EditorExportPreset::set_enc_in_filter(const String &p_filter) {
+ enc_in_filters = p_filter;
+ EditorExport::singleton->save_presets();
+}
+
+String EditorExportPreset::get_enc_in_filter() const {
+ return enc_in_filters;
+}
+
+void EditorExportPreset::set_enc_ex_filter(const String &p_filter) {
+ enc_ex_filters = p_filter;
+ EditorExport::singleton->save_presets();
+}
+
+String EditorExportPreset::get_enc_ex_filter() const {
+ return enc_ex_filters;
+}
+
+void EditorExportPreset::set_enc_pck(bool p_enabled) {
+ enc_pck = p_enabled;
+ EditorExport::singleton->save_presets();
+}
+
+bool EditorExportPreset::get_enc_pck() const {
+ return enc_pck;
+}
+
+void EditorExportPreset::set_enc_directory(bool p_enabled) {
+ enc_directory = p_enabled;
+ EditorExport::singleton->save_presets();
+}
+
+bool EditorExportPreset::get_enc_directory() const {
+ return enc_directory;
+}
+
void EditorExportPreset::set_script_export_mode(int p_mode) {
script_mode = p_mode;
EditorExport::singleton->save_presets();
@@ -292,20 +329,55 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
}
}
-Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
PackData *pd = (PackData *)p_userdata;
SavedData sd;
sd.path_utf8 = p_path.utf8();
sd.ofs = pd->f->get_position();
sd.size = p_data.size();
+ sd.encrypted = false;
- pd->f->store_buffer(p_data.ptr(), p_data.size());
- int pad = _get_pad(PCK_PADDING, sd.size);
+ for (int i = 0; i < p_enc_in_filters.size(); ++i) {
+ if (p_path.matchn(p_enc_in_filters[i]) || p_path.replace("res://", "").matchn(p_enc_in_filters[i])) {
+ sd.encrypted = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < p_enc_ex_filters.size(); ++i) {
+ if (p_path.matchn(p_enc_ex_filters[i]) || p_path.replace("res://", "").matchn(p_enc_ex_filters[i])) {
+ sd.encrypted = false;
+ break;
+ }
+ }
+
+ FileAccessEncrypted *fae = nullptr;
+ FileAccess *ftmp = pd->f;
+
+ if (sd.encrypted) {
+ fae = memnew(FileAccessEncrypted);
+ ERR_FAIL_COND_V(!fae, ERR_SKIP);
+
+ Error err = fae->open_and_parse(ftmp, p_key, FileAccessEncrypted::MODE_WRITE_AES256, false);
+ ERR_FAIL_COND_V(err != OK, ERR_SKIP);
+ ftmp = fae;
+ }
+
+ // Store file content.
+ ftmp->store_buffer(p_data.ptr(), p_data.size());
+
+ if (fae) {
+ fae->release();
+ memdelete(fae);
+ }
+
+ int pad = _get_pad(PCK_PADDING, pd->f->get_position());
for (int i = 0; i < pad; i++) {
- pd->f->store_8(0);
+ pd->f->store_8(Math::rand() % 256);
}
+ // Store MD5 of original file.
{
unsigned char hash[16];
CryptoCore::md5(p_data.ptr(), p_data.size(), hash);
@@ -324,7 +396,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
return OK;
}
-Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
String path = p_path.replace_first("res://", "");
ZipData *zd = (ZipData *)p_userdata;
@@ -694,6 +766,61 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
_edit_filter_list(paths, p_preset->get_include_filter(), false);
_edit_filter_list(paths, p_preset->get_exclude_filter(), true);
+ // Get encryption filters.
+ bool enc_pck = p_preset->get_enc_pck();
+ Vector<String> enc_in_filters;
+ Vector<String> enc_ex_filters;
+ Vector<uint8_t> key;
+
+ if (enc_pck) {
+ Vector<String> enc_in_split = p_preset->get_enc_in_filter().split(",");
+ for (int i = 0; i < enc_in_split.size(); i++) {
+ String f = enc_in_split[i].strip_edges();
+ if (f.empty()) {
+ continue;
+ }
+ enc_in_filters.push_back(f);
+ }
+
+ Vector<String> enc_ex_split = p_preset->get_enc_ex_filter().split(",");
+ for (int i = 0; i < enc_ex_split.size(); i++) {
+ String f = enc_ex_split[i].strip_edges();
+ if (f.empty()) {
+ continue;
+ }
+ enc_ex_filters.push_back(f);
+ }
+
+ // Get encryption key.
+ String script_key = p_preset->get_script_encryption_key().to_lower();
+ key.resize(32);
+ if (script_key.length() == 64) {
+ for (int i = 0; i < 32; i++) {
+ int v = 0;
+ if (i * 2 < script_key.length()) {
+ char32_t ct = script_key[i * 2];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct << 4;
+ }
+
+ if (i * 2 + 1 < script_key.length()) {
+ char32_t ct = script_key[i * 2 + 1];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct;
+ }
+ key.write[i] = v;
+ }
+ }
+ }
+
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
export_plugins.write[i]->set_export_preset(p_preset);
@@ -704,7 +831,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
}
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
- p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
+ p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key);
}
export_plugins.write[i]->_clear();
@@ -756,14 +883,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
if (remap == "path") {
String remapped_path = config->get_value("remap", remap);
Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path);
- err = p_func(p_udata, remapped_path, array, idx, total);
+ err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key);
} else if (remap.begins_with("path.")) {
String feature = remap.get_slice(".", 1);
if (remap_features.has(feature)) {
String remapped_path = config->get_value("remap", remap);
Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path);
- err = p_func(p_udata, remapped_path, array, idx, total);
+ err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key);
}
}
}
@@ -774,7 +901,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
//also save the .import file
Vector<uint8_t> array = FileAccess::get_file_as_array(path + ".import");
- err = p_func(p_udata, path + ".import", array, idx, total);
+ err = p_func(p_udata, path + ".import", array, idx, total, enc_in_filters, enc_ex_filters, key);
if (err != OK) {
return err;
@@ -795,7 +922,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
- p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total);
+ p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key);
if (export_plugins[i]->extra_files[j].remap) {
do_export = false; //if remap, do not
path_remaps.push_back(path);
@@ -815,7 +942,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
//just store it as it comes
if (do_export) {
Vector<uint8_t> array = FileAccess::get_file_as_array(path);
- p_func(p_udata, path, array, idx, total);
+ p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key);
}
}
@@ -851,7 +978,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
new_file.write[j] = utf8[j];
}
- p_func(p_udata, from + ".remap", new_file, idx, total);
+ p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key);
}
} else {
//old remap mode, will still work, but it's unused because it's not multiple pck export friendly
@@ -864,11 +991,11 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
if (icon != String() && FileAccess::exists(icon)) {
Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
- p_func(p_udata, icon, array, idx, total);
+ p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key);
}
if (splash != String() && FileAccess::exists(splash) && icon != splash) {
Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
- p_func(p_udata, splash, array, idx, total);
+ p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key);
}
String config_file = "project.binary";
@@ -877,7 +1004,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
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);
+ p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key);
return OK;
}
@@ -953,6 +1080,17 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
f->store_32(VERSION_MINOR);
f->store_32(VERSION_PATCH);
+ uint32_t pack_flags = 0;
+ bool enc_pck = p_preset->get_enc_pck();
+ bool enc_directory = p_preset->get_enc_directory();
+ if (enc_pck && enc_directory) {
+ pack_flags |= PACK_DIR_ENCRYPTED;
+ }
+ f->store_32(pack_flags); // flags
+
+ uint64_t file_base_ofs = f->get_position();
+ f->store_64(0); // files base
+
for (int i = 0; i < 16; i++) {
//reserved
f->store_32(0);
@@ -960,40 +1098,82 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
f->store_32(pd.file_ofs.size()); //amount of files
- int64_t header_size = f->get_position();
+ FileAccessEncrypted *fae = nullptr;
+ FileAccess *fhead = f;
+
+ if (enc_pck && enc_directory) {
+ String script_key = p_preset->get_script_encryption_key().to_lower();
+ Vector<uint8_t> key;
+ key.resize(32);
+ if (script_key.length() == 64) {
+ for (int i = 0; i < 32; i++) {
+ int v = 0;
+ if (i * 2 < script_key.length()) {
+ char32_t ct = script_key[i * 2];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct << 4;
+ }
- //precalculate header size
+ if (i * 2 + 1 < script_key.length()) {
+ char32_t ct = script_key[i * 2 + 1];
+ if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = 10 + ct - 'a';
+ }
+ v |= ct;
+ }
+ key.write[i] = v;
+ }
+ }
+ fae = memnew(FileAccessEncrypted);
+ ERR_FAIL_COND_V(!fae, ERR_SKIP);
- for (int i = 0; i < pd.file_ofs.size(); i++) {
- header_size += 4; // size of path string (32 bits is enough)
- int string_len = pd.file_ofs[i].path_utf8.length();
- header_size += string_len + _get_pad(4, string_len); ///size of path string
- header_size += 8; // offset to file _with_ header size included
- header_size += 8; // size of file
- header_size += 16; // md5
- }
+ err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_WRITE_AES256, false);
+ ERR_FAIL_COND_V(err != OK, ERR_SKIP);
- int header_padding = _get_pad(PCK_PADDING, header_size);
+ fhead = fae;
+ }
for (int i = 0; i < pd.file_ofs.size(); i++) {
int string_len = pd.file_ofs[i].path_utf8.length();
int pad = _get_pad(4, string_len);
- f->store_32(string_len + pad);
- f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len);
+ fhead->store_32(string_len + pad);
+ fhead->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len);
for (int j = 0; j < pad; j++) {
- f->store_8(0);
+ fhead->store_8(0);
+ }
+
+ fhead->store_64(pd.file_ofs[i].ofs);
+ fhead->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is
+ fhead->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file
+ uint32_t flags = 0;
+ if (pd.file_ofs[i].encrypted) {
+ flags |= PACK_FILE_ENCRYPTED;
}
+ fhead->store_32(flags);
+ }
- f->store_64(pd.file_ofs[i].ofs + header_padding + header_size);
- f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is
- f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file
+ if (fae) {
+ fae->release();
+ memdelete(fae);
}
+ int header_padding = _get_pad(PCK_PADDING, f->get_position());
for (int i = 0; i < header_padding; i++) {
- f->store_8(0);
+ f->store_8(Math::rand() % 256);
}
+ uint64_t file_base = f->get_position();
+ f->seek(file_base_ofs);
+ f->store_64(file_base); // update files base
+ f->seek(file_base);
+
// Save the rest of the data.
ftmp = FileAccess::open(tmppath, FileAccess::READ);
@@ -1162,6 +1342,10 @@ void EditorExport::_save() {
config->set_value(section, "exclude_filter", preset->get_exclude_filter());
config->set_value(section, "export_path", preset->get_export_path());
config->set_value(section, "patch_list", preset->get_patches());
+ config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter());
+ config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter());
+ config->set_value(section, "encrypt_pck", preset->get_enc_pck());
+ config->set_value(section, "encrypt_directory", preset->get_enc_directory());
config->set_value(section, "script_export_mode", preset->get_script_export_mode());
config->set_value(section, "script_encryption_key", preset->get_script_encryption_key());
@@ -1222,6 +1406,20 @@ String EditorExportPlatform::test_etc2() const {
return String();
}
+String EditorExportPlatform::test_etc2_or_pvrtc() const {
+ String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2");
+ bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc");
+
+ if (driver == "GLES2" && !pvrtc_supported) {
+ return TTR("Target platform requires 'PVRTC' texture compression for GLES2. Enable 'Import Pvrtc' in Project Settings.");
+ } else if (driver == "Vulkan" && !etc2_supported && !pvrtc_supported) {
+ // FIXME: Review if this is true for Vulkan.
+ return TTR("Target platform requires 'ETC2' or 'PVRTC' texture compression for Vulkan. Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings.");
+ }
+ return String();
+}
+
int EditorExport::get_export_preset_count() const {
return export_presets.size();
}
@@ -1337,6 +1535,18 @@ void EditorExport::load_config() {
preset->add_patch(patch_list[i]);
}
+ if (config->has_section_key(section, "encrypt_pck")) {
+ preset->set_enc_pck(config->get_value(section, "encrypt_pck"));
+ }
+ if (config->has_section_key(section, "encrypt_directory")) {
+ preset->set_enc_directory(config->get_value(section, "encrypt_directory"));
+ }
+ if (config->has_section_key(section, "encryption_include_filters")) {
+ preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters"));
+ }
+ if (config->has_section_key(section, "encryption_exclude_filters")) {
+ preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters"));
+ }
if (config->has_section_key(section, "script_export_mode")) {
preset->set_script_export_mode(config->get_value(section, "script_export_mode"));
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index bb701b94ec..fa6be88302 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -55,7 +55,6 @@ public:
enum ScriptExportMode {
MODE_SCRIPT_TEXT,
MODE_SCRIPT_COMPILED,
- MODE_SCRIPT_ENCRYPTED,
};
private:
@@ -81,6 +80,11 @@ private:
String custom_features;
+ String enc_in_filters;
+ String enc_ex_filters;
+ bool enc_pck = false;
+ bool enc_directory = false;
+
int script_mode = MODE_SCRIPT_COMPILED;
String script_key;
@@ -129,6 +133,18 @@ public:
void set_export_path(const String &p_path);
String get_export_path() const;
+ void set_enc_in_filter(const String &p_filter);
+ String get_enc_in_filter() const;
+
+ void set_enc_ex_filter(const String &p_filter);
+ String get_enc_ex_filter() const;
+
+ void set_enc_pck(bool p_enabled);
+ bool get_enc_pck() const;
+
+ void set_enc_directory(bool p_enabled);
+ bool get_enc_directory() const;
+
void set_script_export_mode(int p_mode);
int get_script_export_mode() const;
@@ -156,13 +172,14 @@ class EditorExportPlatform : public Reference {
GDCLASS(EditorExportPlatform, Reference);
public:
- typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
+ typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so);
private:
struct SavedData {
uint64_t ofs;
uint64_t size;
+ bool encrypted;
Vector<uint8_t> md5;
CharString path_utf8;
@@ -192,8 +209,8 @@ private:
void _export_find_dependencies(const String &p_path, Set<String> &p_paths);
void gen_debug_flags(Vector<String> &r_flags, int p_flags);
- static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
- static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
+ static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
+ static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
void _edit_files_with_filter(DirAccess *da, const Vector<String> &p_filters, Set<String> &r_list, bool exclude);
void _edit_filter_list(Set<String> &r_list, const String &p_filter, bool exclude);
@@ -260,6 +277,7 @@ public:
virtual Ref<Texture2D> get_run_icon() const { return get_logo(); }
String test_etc2() const; //generic test for etc2 since most platforms use it
+ String test_etc2_or_pvrtc() const; // test for etc2 or pvrtc support for iOS
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0;
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0;
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index f68cc3b323..7335563dd9 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -41,9 +41,9 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = {
TTRC("Script Editor"),
TTRC("Asset Library"),
TTRC("Scene Tree Editing"),
- TTRC("Import Dock"),
TTRC("Node Dock"),
- TTRC("FileSystem and Import Docks")
+ TTRC("FileSystem Dock"),
+ TTRC("Import Dock"),
};
const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = {
@@ -51,9 +51,9 @@ const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = {
"script",
"asset_lib",
"scene_tree",
- "import_dock",
"node_dock",
- "filesystem_dock"
+ "filesystem_dock",
+ "import_dock",
};
void EditorFeatureProfile::set_disable_class(const StringName &p_class, bool p_disabled) {
@@ -271,9 +271,9 @@ void EditorFeatureProfile::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_SCRIPT);
BIND_ENUM_CONSTANT(FEATURE_ASSET_LIB);
BIND_ENUM_CONSTANT(FEATURE_SCENE_TREE);
- BIND_ENUM_CONSTANT(FEATURE_IMPORT_DOCK);
BIND_ENUM_CONSTANT(FEATURE_NODE_DOCK);
BIND_ENUM_CONSTANT(FEATURE_FILESYSTEM_DOCK);
+ BIND_ENUM_CONSTANT(FEATURE_IMPORT_DOCK);
BIND_ENUM_CONSTANT(FEATURE_MAX);
}
@@ -678,9 +678,16 @@ void EditorFeatureProfileManager::_update_selected_profile() {
TreeItem *root = class_list->create_item();
TreeItem *features = class_list->create_item(root);
+ TreeItem *last_feature;
features->set_text(0, TTR("Enabled Features:"));
for (int i = 0; i < EditorFeatureProfile::FEATURE_MAX; i++) {
- TreeItem *feature = class_list->create_item(features);
+ TreeItem *feature;
+ if (i == EditorFeatureProfile::FEATURE_IMPORT_DOCK) {
+ feature = class_list->create_item(last_feature);
+ } else {
+ feature = class_list->create_item(features);
+ last_feature = feature;
+ }
feature->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
feature->set_text(0, TTRGET(EditorFeatureProfile::get_feature_name(EditorFeatureProfile::Feature(i))));
feature->set_selectable(0, true);
diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h
index 38413e35a2..d0d08c61f4 100644
--- a/editor/editor_feature_profile.h
+++ b/editor/editor_feature_profile.h
@@ -49,9 +49,9 @@ public:
FEATURE_SCRIPT,
FEATURE_ASSET_LIB,
FEATURE_SCENE_TREE,
- FEATURE_IMPORT_DOCK,
FEATURE_NODE_DOCK,
FEATURE_FILESYSTEM_DOCK,
+ FEATURE_IMPORT_DOCK,
FEATURE_MAX
};
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index bce34db740..30aebd2b1f 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -244,7 +244,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
class_desc->push_cell();
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
} else {
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
}
@@ -761,7 +761,7 @@ void EditorHelp::_update_doc() {
signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
class_desc->push_font(doc_code_font); // monofont
class_desc->push_color(headline_color);
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
_add_text(cd.signals[i].name);
class_desc->pop();
@@ -876,7 +876,7 @@ void EditorHelp::_update_doc() {
class_desc->push_font(doc_code_font);
class_desc->push_color(headline_color);
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
_add_text(enum_list[i].name);
class_desc->pop();
@@ -890,7 +890,7 @@ void EditorHelp::_update_doc() {
if (enum_list[i].description != "") {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
- static const CharType dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 };
+ static const char32_t dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 };
class_desc->add_text(String(dash));
_add_text(DTR(enum_list[i].description));
class_desc->pop();
@@ -937,12 +937,12 @@ void EditorHelp::_update_doc() {
Vector<float> color = stripped.split_floats(",");
if (color.size() >= 3) {
class_desc->push_color(Color(color[0], color[1], color[2]));
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
class_desc->pop();
}
} else {
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
}
@@ -960,7 +960,7 @@ void EditorHelp::_update_doc() {
if (constants[i].description != "") {
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
- static const CharType dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 };
+ static const char32_t dash[6] = { ' ', ' ', 0x2013 /* en dash */, ' ', ' ', 0 };
class_desc->add_text(String(dash));
_add_text(DTR(constants[i].description));
class_desc->pop();
@@ -1002,7 +1002,7 @@ void EditorHelp::_update_doc() {
class_desc->push_cell();
class_desc->push_font(doc_code_font);
- static const CharType prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
+ static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 };
class_desc->add_text(String(prefix));
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 9595eb8a72..6fbafc7ff3 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -79,7 +79,15 @@ void EditorLog::_clear_request() {
}
void EditorLog::_copy_request() {
- log->selection_copy();
+ String text = log->get_selected_text();
+
+ if (text == "") {
+ text = log->get_text();
+ }
+
+ if (text != "") {
+ DisplayServer::get_singleton()->clipboard_set(text);
+ }
}
void EditorLog::clear() {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 8544bb8856..8edda3123b 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -157,6 +157,7 @@
#include "editor/plugins/sprite_frames_editor_plugin.h"
#include "editor/plugins/style_box_editor_plugin.h"
#include "editor/plugins/text_editor.h"
+#include "editor/plugins/texture_3d_editor_plugin.h"
#include "editor/plugins/texture_editor_plugin.h"
#include "editor/plugins/texture_layered_editor_plugin.h"
#include "editor/plugins/texture_region_editor_plugin.h"
@@ -478,6 +479,8 @@ void EditorNode::_notification(int p_what) {
RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit"));
bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic);
+ bool glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality");
+ RS::get_singleton()->environment_glow_set_use_high_quality(glow_high_quality);
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality);
RS::SubSurfaceScatteringQuality sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality")));
@@ -2542,6 +2545,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
} break;
case RUN_PROJECT_DATA_FOLDER: {
+ // ensure_user_data_dir() to prevent the edge case: "Open Project Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved
+ OS::get_singleton()->ensure_user_data_dir();
OS::get_singleton()->shell_open(String("file://") + OS::get_singleton()->get_user_data_dir());
} break;
case FILE_EXPLORE_ANDROID_BUILD_TEMPLATES: {
@@ -2623,6 +2628,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case SETTINGS_TOGGLE_CONSOLE: {
bool was_visible = DisplayServer::get_singleton()->is_console_visible();
DisplayServer::get_singleton()->console_set_visible(!was_visible);
+ EditorSettings::get_singleton()->set_setting("interface/editor/hide_console_window", was_visible);
} break;
case EDITOR_SCREENSHOT: {
screenshot_timer->start();
@@ -2815,9 +2821,9 @@ void EditorNode::_discard_changes(const String &p_str) {
}
void EditorNode::_update_file_menu_opened() {
- Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
+ 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");
+ 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());
@@ -4710,10 +4716,10 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
scene_tabs_context_menu->add_separator();
- Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene");
+ 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");
+ 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()) {
@@ -5344,9 +5350,11 @@ void EditorNode::_feature_profile_changed() {
TabContainer *node_tabs = cast_to<TabContainer>(node_dock->get_parent());
TabContainer *fs_tabs = cast_to<TabContainer>(filesystem_dock->get_parent());
if (profile.is_valid()) {
- import_tabs->set_tab_hidden(import_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK));
node_tabs->set_tab_hidden(node_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK));
- fs_tabs->set_tab_hidden(filesystem_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK));
+ // The Import dock is useless without the FileSystem dock. Ensure the configuration is valid.
+ bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK);
+ fs_tabs->set_tab_hidden(filesystem_dock->get_index(), fs_dock_disabled);
+ import_tabs->set_tab_hidden(import_dock->get_index(), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK));
main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D));
main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT));
@@ -5615,10 +5623,10 @@ EditorNode::EditorNode() {
import_cubemap_array->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP_ARRAY);
ResourceFormatImporter::get_singleton()->add_importer(import_cubemap_array);
- /*Ref<ResourceImporterLayeredTexture> import_3d;
+ Ref<ResourceImporterLayeredTexture> import_3d;
import_3d.instance();
import_3d->set_mode(ResourceImporterLayeredTexture::MODE_3D);
- ResourceFormatImporter::get_singleton()->add_importer(import_3d);*/
+ ResourceFormatImporter::get_singleton()->add_importer(import_3d);
Ref<ResourceImporterImage> import_image;
import_image.instance();
@@ -6192,7 +6200,9 @@ EditorNode::EditorNode() {
#else
p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN);
#endif
-#ifdef WINDOWS_ENABLED
+#if defined(WINDOWS_ENABLED) && defined(WINDOWS_SUBSYSTEM_CONSOLE)
+ // The console can only be toggled if the application was built for the console subsystem,
+ // not the GUI subsystem.
p->add_item(TTR("Toggle System Console"), SETTINGS_TOGGLE_CONSOLE);
#endif
p->add_separator();
@@ -6617,6 +6627,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(CurveEditorPlugin(this)));
add_editor_plugin(memnew(TextureEditorPlugin(this)));
add_editor_plugin(memnew(TextureLayeredEditorPlugin(this)));
+ add_editor_plugin(memnew(Texture3DEditorPlugin(this)));
add_editor_plugin(memnew(AudioStreamEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(Skeleton3DEditorPlugin(this)));
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index b49c50fa31..7fada633c9 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -192,9 +192,9 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
String exec = OS::get_singleton()->get_executable_path();
- printf("Running: %ls", exec.c_str());
+ printf("Running: %s", exec.utf8().get_data());
for (List<String>::Element *E = args.front(); E; E = E->next()) {
- printf(" %ls", E->get().c_str());
+ printf(" %s", E->get().utf8().get_data());
};
printf("\n");
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 9a834977fd..422534a2e1 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -121,7 +121,7 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
}
if (preset.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("No runnable export preset found for this platform.\nPlease add a runnable preset in the export menu."));
+ EditorNode::get_singleton()->show_warning(TTR("No runnable export preset found for this platform.\nPlease add a runnable preset in the Export menu or define an existing preset as runnable."));
return;
}
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index eabbf6b0d8..cf19b54cff 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -238,7 +238,7 @@ void SectionedInspector::update_category_list() {
continue;
}
- if (!filter.empty() && !filter.is_subsequence_ofi(pi.name) && !filter.is_subsequence_ofi(pi.name.replace("/", " ").capitalize())) {
+ if (!filter.empty() && pi.name.findn(filter) == -1 && pi.name.replace("/", " ").capitalize().findn(filter) == -1) {
continue;
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 7b24e6967a..ac27c4a837 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -77,7 +77,7 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value)
String name = arr[i];
Ref<InputEvent> shortcut = arr[i + 1];
- Ref<ShortCut> sc;
+ Ref<Shortcut> sc;
sc.instance();
sc->set_shortcut(shortcut);
add_shortcut(name, sc);
@@ -120,8 +120,8 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name.operator String() == "shortcuts") {
Array arr;
- for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
- Ref<ShortCut> sc = E->get();
+ for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) {
+ Ref<Shortcut> sc = E->get();
if (optimize_save) {
if (!sc->has_meta("original")) {
@@ -334,6 +334,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/automatically_open_screenshots", true);
_initial_set("interface/editor/single_window_mode", false);
hints["interface/editor/single_window_mode"] = PropertyInfo(Variant::BOOL, "interface/editor/single_window_mode", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ _initial_set("interface/editor/hide_console_window", false);
_initial_set("interface/editor/save_each_scene_on_quit", true); // Regression
_initial_set("interface/editor/quit_confirmation", true);
@@ -444,7 +445,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_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);
@@ -706,8 +706,8 @@ void EditorSettings::_load_default_text_editor_theme() {
_initial_set("text_editor/highlighting/member_variable_color", Color(0.9, 0.31, 0.35));
_initial_set("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4));
_initial_set("text_editor/highlighting/bookmark_color", Color(0.08, 0.49, 0.98));
- _initial_set("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2));
- _initial_set("text_editor/highlighting/executing_line_color", Color(0.2, 0.8, 0.2, 0.4));
+ _initial_set("text_editor/highlighting/breakpoint_color", Color(0.9, 0.29, 0.3));
+ _initial_set("text_editor/highlighting/executing_line_color", Color(0.98, 0.89, 0.27));
_initial_set("text_editor/highlighting/code_folding_color", Color(0.8, 0.8, 0.8, 0.8));
_initial_set("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
_initial_set("text_editor/highlighting/search_result_border_color", Color(0.41, 0.61, 0.91, 0.38));
@@ -935,6 +935,7 @@ void EditorSettings::create() {
String config_file_name = "editor_settings-" + itos(VERSION_MAJOR) + ".tres";
config_file_path = config_dir.plus_file(config_file_name);
if (!dir->file_exists(config_file_name)) {
+ memdelete(dir);
goto fail;
}
@@ -1479,50 +1480,50 @@ String EditorSettings::get_editor_layouts_config() const {
// Shortcuts
-void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut) {
+void EditorSettings::add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut) {
shortcuts[p_name] = p_shortcut;
}
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);
+ const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name);
ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + ".");
return E->get()->is_shortcut(p_event);
}
-Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const {
- const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name);
+Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const {
+ const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name);
if (!E) {
- return Ref<ShortCut>();
+ return Ref<Shortcut>();
}
return E->get();
}
void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) {
- for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
+ for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) {
r_shortcuts->push_back(E->key());
}
}
-Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) {
+Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) {
if (!EditorSettings::get_singleton()) {
return nullptr;
}
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
ERR_FAIL_COND_V_MSG(!sc.is_valid(), sc, "Used ED_GET_SHORTCUT with invalid shortcut: " + p_path + ".");
return sc;
}
-struct ShortCutMapping {
+struct ShortcutMapping {
const char *path;
uint32_t keycode;
};
-Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
+Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
#ifdef OSX_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (p_keycode == KEY_DELETE) {
@@ -1543,7 +1544,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
}
if (!EditorSettings::get_singleton()) {
- Ref<ShortCut> sc;
+ Ref<Shortcut> sc;
sc.instance();
sc->set_name(p_name);
sc->set_shortcut(ie);
@@ -1551,7 +1552,7 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
return sc;
}
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
if (sc.is_valid()) {
sc->set_name(p_name); //keep name (the ones that come from disk have no name)
sc->set_meta("original", ie); //to compare against changes
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 13aebb7ea6..4896fb58db 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -85,7 +85,7 @@ private:
int last_order;
Ref<Resource> clipboard;
- Map<String, Ref<ShortCut>> shortcuts;
+ Map<String, Ref<Shortcut>> shortcuts;
String resource_path;
String settings_dir;
@@ -182,9 +182,9 @@ public:
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);
+ void add_shortcut(const String &p_name, Ref<Shortcut> &p_shortcut);
bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
- Ref<ShortCut> get_shortcut(const String &p_name) const;
+ Ref<Shortcut> get_shortcut(const String &p_name) const;
void get_shortcut_list(List<String> *r_shortcuts);
void notify_changes();
@@ -203,7 +203,7 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re
Variant _EDITOR_GET(const String &p_setting);
#define ED_IS_SHORTCUT(p_name, p_ev) (EditorSettings::get_singleton()->is_shortcut(p_name, p_ev))
-Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0);
-Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path);
+Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode = 0);
+Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path);
#endif // EDITOR_SETTINGS_H
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index d76a3d2da7..ac61a75a6c 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -356,7 +356,12 @@ String EditorSpinSlider::get_label() const {
}
void EditorSpinSlider::_evaluate_input_text() {
- String text = value_input->get_text();
+ // Replace comma with dot to support it as decimal separator (GH-6028).
+ // This prevents using functions like `pow()`, but using functions
+ // in EditorSpinSlider is a barely known (and barely used) feature.
+ // Instead, we'd rather support German/French keyboard layouts out of the box.
+ const String text = value_input->get_text().replace(",", ".");
+
Ref<Expression> expr;
expr.instance();
Error err = expr->parse(text);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 8d54bc8021..79525ced51 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -218,8 +218,15 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
// Generate icons.
if (!p_only_thumbs) {
for (int i = 0; i < editor_icons_count; i++) {
+ float icon_scale = EDSCALE;
+
+ // Always keep the DefaultProjectIcon at the default size
+ if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) {
+ icon_scale = 1.0f;
+ }
+
const int is_exception = exceptions.has(editor_icons_names[i]);
- const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception);
+ const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale);
p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
@@ -868,12 +875,24 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("side_margin", "TabContainer", 0);
theme->set_icon("tab", "TextEdit", theme->get_icon("GuiTab", "EditorIcons"));
theme->set_icon("space", "TextEdit", theme->get_icon("GuiSpace", "EditorIcons"));
- theme->set_icon("folded", "TextEdit", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
- theme->set_icon("fold", "TextEdit", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_color("font_color", "TextEdit", font_color);
theme->set_color("caret_color", "TextEdit", font_color);
theme->set_color("selection_color", "TextEdit", font_color_selection);
+ // CodeEdit
+ theme->set_stylebox("normal", "CodeEdit", style_widget);
+ theme->set_stylebox("focus", "CodeEdit", style_widget_hover);
+ theme->set_stylebox("read_only", "CodeEdit", style_widget_disabled);
+ theme->set_constant("side_margin", "TabContainer", 0);
+ theme->set_icon("tab", "CodeEdit", theme->get_icon("GuiTab", "EditorIcons"));
+ theme->set_icon("space", "CodeEdit", theme->get_icon("GuiSpace", "EditorIcons"));
+ theme->set_icon("folded", "CodeEdit", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
+ theme->set_icon("can_fold", "CodeEdit", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
+ theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons"));
+ theme->set_color("font_color", "CodeEdit", font_color);
+ theme->set_color("caret_color", "CodeEdit", font_color);
+ theme->set_color("selection_color", "CodeEdit", font_color_selection);
+
// H/VSplitContainer
theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1));
theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon("GuiHsplitBg", "EditorIcons"), 1, 1, 1, 1));
@@ -1179,7 +1198,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3);
const Color bookmark_color = Color(0.08, 0.49, 0.98);
const Color breakpoint_color = error_color;
- const Color executing_line_color = Color(0.2, 0.8, 0.2, 0.4);
+ const Color executing_line_color = Color(0.98, 0.89, 0.27);
const Color code_folding_color = alpha3;
const Color search_result_color = alpha1;
const Color search_result_border_color = Color(0.41, 0.61, 0.91, 0.38);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 31903c89be..0071f169ac 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -2300,6 +2300,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
// Right click is pressed in the tree.
Vector<String> paths = _tree_get_selected(false);
+ tree_popup->clear();
if (paths.size() == 1) {
if (paths[0].ends_with("/")) {
tree_popup->add_icon_item(get_theme_icon("GuiTreeArrowDown", "EditorIcons"), TTR("Expand All"), FOLDER_EXPAND_ALL);
@@ -2310,7 +2311,6 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
// Popup.
if (!paths.empty()) {
- tree_popup->clear();
tree_popup->set_size(Size2(1, 1));
_file_and_folders_fill_popup(tree_popup, paths);
tree_popup->set_position(tree->get_screen_position() + p_pos);
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index bd4bb57dcf..c2ccbdb08c 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -54,7 +54,7 @@ inline void pop_back(T &container) {
}
// TODO Copied from TextEdit private, would be nice to extract it in a single place
-static bool is_text_char(CharType c) {
+static bool is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
@@ -854,7 +854,7 @@ public:
String get_line(FileAccess *f) {
_line_buffer.clear();
- CharType c = f->get_8();
+ char32_t c = f->get_8();
while (!f->eof_reached()) {
if (c == '\n') {
diff --git a/editor/icons/AutoKey.svg b/editor/icons/AutoKey.svg
index 9852d1360e..acc6665baf 100644
--- a/editor/icons/AutoKey.svg
+++ b/editor/icons/AutoKey.svg
@@ -1 +1 @@
-<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>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><circle cx="8" cy="5" r="4"/><path d="m11 13c0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228-.00001-.99999-.44772-1-1 .00001-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3z" fill-opacity=".99608"/><path d="m4 10c-1.6569 0-3 1.3431-3 3v3h2v-3c.0000096-.5523.44772-1 1-1h1v-2z" fill-opacity=".99608"/><path d="m8 10c-3 0-3 3-3 3s0 3 3 3h1v-2h-1s-1 0-1-1h3 1s0-3-3-3zm-1 1h2v1h-2z"/></g></svg>
diff --git a/editor/icons/ShortCut.svg b/editor/icons/Shortcut.svg
index 4ef16f0401..4ef16f0401 100644
--- a/editor/icons/ShortCut.svg
+++ b/editor/icons/Shortcut.svg
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index f954931cee..bbf62596d0 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -70,7 +70,7 @@ String ResourceImporterLayeredTexture::get_visible_name() const {
return "CubemapArray";
} break;
case MODE_3D: {
- return "3D";
+ return "Texture3D";
} break;
}
@@ -156,15 +156,103 @@ void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_op
}
void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) {
- for (int i = 0; i < p_images.size(); i++) {
- if (p_force_po2) {
- p_images.write[i]->resize_to_po2();
+ Vector<Ref<Image>> mipmap_images; //for 3D
+
+ if (mode == MODE_3D) {
+ //3D saves in its own way
+
+ for (int i = 0; i < p_images.size(); i++) {
+ if (p_images.write[i]->has_mipmaps()) {
+ p_images.write[i]->clear_mipmaps();
+ }
+
+ if (p_force_po2) {
+ p_images.write[i]->resize_to_po2();
+ }
}
if (p_mipmaps) {
- p_images.write[i]->generate_mipmaps();
- } else {
- p_images.write[i]->clear_mipmaps();
+ Vector<Ref<Image>> parent_images = p_images;
+ //create 3D mipmaps, this is horrible, though not used very often
+ int w = p_images[0]->get_width();
+ int h = p_images[0]->get_height();
+ int d = p_images.size();
+
+ while (w > 1 || h > 1 || d > 1) {
+ Vector<Ref<Image>> mipmaps;
+ int mm_w = MAX(1, w >> 1);
+ int mm_h = MAX(1, h >> 1);
+ int mm_d = MAX(1, d >> 1);
+
+ for (int i = 0; i < mm_d; i++) {
+ Ref<Image> mm;
+ mm.instance();
+ mm->create(mm_w, mm_h, false, p_images[0]->get_format());
+ Vector3 pos;
+ pos.z = float(i) * float(d) / float(mm_d) + 0.5;
+ for (int x = 0; x < mm_w; x++) {
+ for (int y = 0; y < mm_h; y++) {
+ pos.x = float(x) * float(w) / float(mm_w) + 0.5;
+ pos.y = float(y) * float(h) / float(mm_h) + 0.5;
+
+ Vector3i posi = Vector3i(pos);
+ Vector3 fract = pos - Vector3(posi);
+ Vector3i posi_n = posi;
+ if (posi_n.x < w - 1) {
+ posi_n.x++;
+ }
+ if (posi_n.y < h - 1) {
+ posi_n.y++;
+ }
+ if (posi_n.z < d - 1) {
+ posi_n.z++;
+ }
+
+ Color c000 = parent_images[posi.z]->get_pixel(posi.x, posi.y);
+ Color c100 = parent_images[posi.z]->get_pixel(posi_n.x, posi.y);
+ Color c010 = parent_images[posi.z]->get_pixel(posi.x, posi_n.y);
+ Color c110 = parent_images[posi.z]->get_pixel(posi_n.x, posi_n.y);
+ Color c001 = parent_images[posi_n.z]->get_pixel(posi.x, posi.y);
+ Color c101 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi.y);
+ Color c011 = parent_images[posi_n.z]->get_pixel(posi.x, posi_n.y);
+ Color c111 = parent_images[posi_n.z]->get_pixel(posi_n.x, posi_n.y);
+
+ Color cx00 = c000.lerp(c100, fract.x);
+ Color cx01 = c001.lerp(c101, fract.x);
+ Color cx10 = c010.lerp(c110, fract.x);
+ Color cx11 = c011.lerp(c111, fract.x);
+
+ Color cy0 = cx00.lerp(cx10, fract.y);
+ Color cy1 = cx01.lerp(cx11, fract.y);
+
+ Color cz = cy0.lerp(cy1, fract.z);
+
+ mm->set_pixel(x, y, cz);
+ }
+ }
+
+ mipmaps.push_back(mm);
+ }
+
+ w = mm_w;
+ h = mm_h;
+ d = mm_d;
+
+ mipmap_images.append_array(mipmaps);
+ parent_images = mipmaps;
+ }
+ }
+ } else {
+ for (int i = 0; i < p_images.size(); i++) {
+ if (p_force_po2) {
+ p_images.write[i]->resize_to_po2();
+ }
+
+ if (p_mipmaps) {
+ p_images.write[i]->generate_mipmaps();
+ } else {
+ p_images.write[i]->clear_mipmaps();
+ }
}
}
@@ -175,13 +263,12 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons
f->store_8('L');
f->store_32(StreamTextureLayered::FORMAT_VERSION);
- f->store_32(p_images.size());
+ f->store_32(p_images.size()); //2d layers or 3d depth
f->store_32(mode);
- f->store_32(0); //dataformat
- f->store_32(0); //mipmap limit
+ f->store_32(0);
- //reserved
f->store_32(0);
+ f->store_32(mipmap_images.size()); // amount of mipmaps
f->store_32(0);
f->store_32(0);
@@ -189,6 +276,10 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons
ResourceImporterTexture::save_to_stex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy);
}
+ for (int i = 0; i < mipmap_images.size(); i++) {
+ ResourceImporterTexture::save_to_stex_format(f, mipmap_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy);
+ }
+
f->close();
}
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 2d50889e9e..b54923be00 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -93,10 +93,6 @@ private:
static const char *compression_formats[];
protected:
- static void _texture_reimport_srgb(const Ref<StreamTexture2D> &p_tex);
- static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex);
- static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex);
-
static ResourceImporterLayeredTexture *singleton;
public:
diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp
index 52cf9c1869..c67e16d371 100644
--- a/editor/input_map_editor.cpp
+++ b/editor/input_map_editor.cpp
@@ -100,7 +100,7 @@ void InputMapEditor::_notification(int p_what) {
}
static bool _validate_action_name(const String &p_name) {
- const CharType *cstr = p_name.c_str();
+ const char32_t *cstr = p_name.get_data();
for (int i = 0; cstr[i]; i++) {
if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' ||
cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) {
diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp
index 2ddcf3d877..6e5fb6389d 100644
--- a/editor/node_3d_editor_gizmos.cpp
+++ b/editor/node_3d_editor_gizmos.cpp
@@ -1912,7 +1912,7 @@ void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> lines;
lines.push_back(Vector3());
- lines.push_back(raycast->get_cast_to());
+ lines.push_back(raycast->get_target_position());
const Ref<StandardMaterial3D> material =
get_material(raycast->is_enabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 49e67f3605..7a3fb1ff52 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -287,7 +287,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
pre_move_edit = vertices2;
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;
+ selected_point = Vertex(edited_point.polygon, edited_point.vertex);
edge_point = PosVertex();
undo_redo->create_action(TTR("Insert Point"));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 3f9f159d7f..ef4ba9819f 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -863,10 +863,11 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2
ERR_FAIL_COND_V(!p_control, Vector2());
Rect2 parent_rect = p_control->get_parent_anchorable_rect();
- ERR_FAIL_COND_V(parent_rect.size.x == 0, Vector2());
- ERR_FAIL_COND_V(parent_rect.size.y == 0, Vector2());
- return (p_control->get_transform().xform(position) - parent_rect.position) / parent_rect.size;
+ Vector2 output = Vector2();
+ output.x = (parent_rect.size.x == 0) ? 0.0 : (p_control->get_transform().xform(position).x - parent_rect.position.x) / parent_rect.size.x;
+ output.y = (parent_rect.size.y == 0) ? 0.0 : (p_control->get_transform().xform(position).y - parent_rect.position.y) / parent_rect.size.y;
+ return output;
}
void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state) {
@@ -3824,12 +3825,12 @@ void CanvasItemEditor::_draw_viewport() {
_draw_grid();
_draw_ruler_tool();
- _draw_selection();
_draw_axis();
if (editor->get_edited_scene()) {
_draw_locks_and_groups(editor->get_edited_scene());
_draw_invisible_nodes_positions(editor->get_edited_scene());
}
+ _draw_selection();
RID ci = viewport->get_canvas_item();
RenderingServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
@@ -6256,7 +6257,7 @@ void CanvasItemEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
+ accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data()));
accept->popup_centered();
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index ea58fb1e36..859e80befe 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -400,11 +400,11 @@ private:
Ref<Texture2D> select_handle;
Ref<Texture2D> anchor_handle;
- Ref<ShortCut> drag_pivot_shortcut;
- Ref<ShortCut> set_pivot_shortcut;
- Ref<ShortCut> multiply_grid_step_shortcut;
- Ref<ShortCut> divide_grid_step_shortcut;
- Ref<ShortCut> pan_view_shortcut;
+ Ref<Shortcut> drag_pivot_shortcut;
+ Ref<Shortcut> set_pivot_shortcut;
+ Ref<Shortcut> multiply_grid_step_shortcut;
+ Ref<Shortcut> divide_grid_step_shortcut;
+ Ref<Shortcut> pan_view_shortcut;
bool _is_node_locked(const Node *p_node);
bool _is_node_movable(const Node *p_node, bool p_popup_warning = false);
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 0a4d173923..0747e42045 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -47,7 +47,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d
ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open"));
ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor"));
- // File Server for deploy with remote fs.
+ // File Server for deploy with remote filesystem.
file_server = memnew(EditorFileServer);
EditorDebuggerNode *debugger = memnew(EditorDebuggerNode);
@@ -59,19 +59,31 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d
PopupMenu *p = debug_menu->get_popup();
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
- p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network FS")), RUN_FILE_SERVER);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint."));
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, using one-click deploy will make the executable attempt to connect to this computer's IP so the running project can be debugged.\nThis option is intended to be used for remote debugging (typically with a mobile device).\nYou don't need to enable it to use the GDScript debugger locally."));
+ p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network Filesystem")), RUN_FILE_SERVER);
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, using one-click deploy for Android will only export an executable without the project data.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploying will use the USB cable for faster performance. This option speeds up testing for projects with large assets."));
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on."));
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, collision shapes and raycast nodes (for 2D and 3D) will be visible in the running project."));
p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on."));
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, navigation meshes and polygons will be visible in the running project."));
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Sync Scene Changes")), RUN_LIVE_DEBUG);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
- p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Sync Script Changes")), RUN_RELOAD_SCRIPTS);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
+ p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Synchronize Scene Changes")), RUN_LIVE_DEBUG);
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, any changes made to the scene in the editor will be replicated in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled."));
+ p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Synchronize Script Changes")), RUN_RELOAD_SCRIPTS);
+ p->set_item_tooltip(
+ p->get_item_count() - 1,
+ TTR("When this option is enabled, any script that is saved will be reloaded in the running project.\nWhen used remotely on a device, this is more efficient when the network filesystem option is enabled."));
// Multi-instance, start/stop
instances_menu = memnew(PopupMenu);
diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h
index 5536f2daa2..10fd1151de 100644
--- a/editor/plugins/editor_debugger_plugin.h
+++ b/editor/plugins/editor_debugger_plugin.h
@@ -39,7 +39,7 @@ class EditorDebuggerPlugin : public Control {
GDCLASS(EditorDebuggerPlugin, Control);
private:
- ScriptEditorDebugger *debugger;
+ ScriptEditorDebugger *debugger = nullptr;
void _breaked(bool p_really_did, bool p_can_debug);
void _started();
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 2889cb50a0..3cf4dc5ac8 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -466,7 +466,7 @@ EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
@@ -525,7 +525,7 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
bool prev_is_text = false;
bool in_keyword = false;
for (int i = 0; i < code.length(); i++) {
- CharType c = code[i];
+ char32_t c = code[i];
if (c > 32) {
if (col < thumbnail_size) {
Color color = text_color;
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 1b65987af0..5b241deab0 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -138,6 +138,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(shape);
+ cshape->set_transform(node->get_transform());
Node *owner = node->get_owner();
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 21a75c2f5d..944bf9913c 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -900,12 +900,15 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
float dist = r.distance_to(gt.origin);
-
- if (dist > gs * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gs * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
- float d = ray_pos.distance_to(r);
- if (d < col_d) {
- col_d = d;
- col_axis = i;
+ Vector3 r_dir = (r - gt.origin).normalized();
+
+ if (_get_camera_normal().dot(r_dir) <= 0.005) {
+ if (dist > gs * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gs * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
+ float d = ray_pos.distance_to(r);
+ if (d < col_d) {
+ col_d = d;
+ col_axis = i;
+ }
}
}
}
@@ -2246,7 +2249,7 @@ Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouse
}
static bool is_shortcut_pressed(const String &p_path) {
- Ref<ShortCut> shortcut = ED_GET_SHORTCUT(p_path);
+ Ref<Shortcut> shortcut = ED_GET_SHORTCUT(p_path);
if (shortcut.is_null()) {
return false;
}
@@ -3125,6 +3128,14 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer);
}
+
+ // Rotation white outline
+ rotate_gizmo_instance[3] = RS::get_singleton()->instance_create();
+ RS::get_singleton()->instance_set_base(rotate_gizmo_instance[3], spatial_editor->get_rotate_gizmo(3)->get_rid());
+ RS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[3], get_tree()->get_root()->get_world_3d()->get_scenario());
+ RS::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false);
+ RS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[3], RS::SHADOW_CASTING_SETTING_OFF);
+ RS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[3], layer);
}
void Node3DEditorViewport::_finish_gizmo_instances() {
@@ -3135,6 +3146,8 @@ void Node3DEditorViewport::_finish_gizmo_instances() {
RS::get_singleton()->free(scale_gizmo_instance[i]);
RS::get_singleton()->free(scale_plane_gizmo_instance[i]);
}
+ // Rotation white outline
+ RS::get_singleton()->free(rotate_gizmo_instance[3]);
}
void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
@@ -3226,6 +3239,8 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false);
}
+ // Rotation white outline
+ RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false);
return;
}
@@ -3264,6 +3279,9 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
RenderingServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], xform);
RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE));
}
+ // Rotation white outline
+ RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform);
+ RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE));
}
void Node3DEditorViewport::set_state(const Dictionary &p_state) {
@@ -3729,7 +3747,7 @@ void Node3DEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
+ accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.get_data()));
accept->popup_centered();
}
}
@@ -4403,7 +4421,7 @@ void Node3DEditor::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_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]);
+ rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? rotate_gizmo_color_hl[i] : rotate_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]);
}
@@ -5287,37 +5305,122 @@ void Node3DEditor::_init_indicators() {
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
- Vector3 circle[5] = {
- ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
- ivec * -0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
- ivec * -0.02 + ivec2 * -0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
- ivec * 0.02 + ivec2 * -0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
- ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
- };
+ int n = 128; // number of circle segments
+ int m = 6; // number of thickness segments
- for (int k = 0; k < 64; k++) {
- Basis ma(ivec, Math_PI * 2 * float(k) / 64);
- Basis mb(ivec, Math_PI * 2 * float(k + 1) / 64);
+ for (int j = 0; j < n; ++j) {
+ Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n);
- for (int j = 0; j < 4; j++) {
- Vector3 points[4] = {
- ma.xform(circle[j]),
- mb.xform(circle[j]),
- mb.xform(circle[j + 1]),
- ma.xform(circle[j + 1]),
- };
- surftool->add_vertex(points[0]);
- surftool->add_vertex(points[1]);
- surftool->add_vertex(points[2]);
+ Vector3 vertex = basis.xform(ivec2 * GIZMO_CIRCLE_SIZE);
- surftool->add_vertex(points[0]);
- surftool->add_vertex(points[2]);
- surftool->add_vertex(points[3]);
+ for (int k = 0; k < m; ++k) {
+ Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m));
+ Vector3 normal = ivec * ofs.x + ivec2 * ofs.y;
+
+ surftool->add_normal(basis.xform(normal));
+ surftool->add_vertex(vertex);
}
}
- surftool->set_material(mat);
- surftool->commit(rotate_gizmo[i]);
+ for (int j = 0; j < n; ++j) {
+ for (int k = 0; k < m; ++k) {
+ int current_ring = j * m;
+ int next_ring = ((j + 1) % n) * m;
+ int current_segment = k;
+ int next_segment = (k + 1) % m;
+
+ surftool->add_index(current_ring + next_segment);
+ surftool->add_index(current_ring + current_segment);
+ surftool->add_index(next_ring + current_segment);
+
+ surftool->add_index(next_ring + current_segment);
+ surftool->add_index(next_ring + next_segment);
+ surftool->add_index(current_ring + next_segment);
+ }
+ }
+
+ Ref<Shader> rotate_shader = memnew(Shader);
+
+ rotate_shader->set_code("\n"
+ "shader_type spatial; \n"
+ "render_mode unshaded, depth_test_disabled; \n"
+ "uniform vec4 albedo; \n"
+ "\n"
+ "mat3 orthonormalize(mat3 m) { \n"
+ " vec3 x = normalize(m[0]); \n"
+ " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
+ " vec3 z = m[2] - x * dot(x, m[2]); \n"
+ " z = normalize(z - y * (dot(y,m[2]))); \n"
+ " return mat3(x,y,z); \n"
+ "} \n"
+ "\n"
+ "void vertex() { \n"
+ " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
+ " vec3 n = mv * VERTEX; \n"
+ " float orientation = dot(vec3(0,0,-1),n); \n"
+ " if (orientation <= 0.005) { \n"
+ " VERTEX += NORMAL*0.02; \n"
+ " } \n"
+ "} \n"
+ "\n"
+ "void fragment() { \n"
+ " ALBEDO = albedo.rgb; \n"
+ " ALPHA = albedo.a; \n"
+ "}");
+
+ Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial);
+ rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX);
+ rotate_mat->set_shader(rotate_shader);
+ rotate_mat->set_shader_param("albedo", col);
+ rotate_gizmo_color[i] = rotate_mat;
+
+ Array arrays = surftool->commit_to_arrays();
+ rotate_gizmo[i]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays);
+ rotate_gizmo[i]->surface_set_material(0, rotate_mat);
+
+ Ref<ShaderMaterial> rotate_mat_hl = rotate_mat->duplicate();
+ rotate_mat_hl->set_shader_param("albedo", Color(col.r, col.g, col.b, 1.0));
+ rotate_gizmo_color_hl[i] = rotate_mat_hl;
+
+ if (i == 2) { // Rotation white outline
+ Ref<ShaderMaterial> border_mat = rotate_mat->duplicate();
+
+ Ref<Shader> border_shader = memnew(Shader);
+ border_shader->set_code("\n"
+ "shader_type spatial; \n"
+ "render_mode unshaded, depth_test_disabled; \n"
+ "uniform vec4 albedo; \n"
+ "\n"
+ "mat3 orthonormalize(mat3 m) { \n"
+ " vec3 x = normalize(m[0]); \n"
+ " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
+ " vec3 z = m[2] - x * dot(x, m[2]); \n"
+ " z = normalize(z - y * (dot(y,m[2]))); \n"
+ " return mat3(x,y,z); \n"
+ "} \n"
+ "\n"
+ "void vertex() { \n"
+ " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
+ " mv = inverse(mv); \n"
+ " VERTEX += NORMAL*0.008; \n"
+ " vec3 camera_dir_local = mv * vec3(0,0,1); \n"
+ " vec3 camera_up_local = mv * vec3(0,1,0); \n"
+ " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
+ " VERTEX = rotation_matrix * VERTEX; \n"
+ "} \n"
+ "\n"
+ "void fragment() { \n"
+ " ALBEDO = albedo.rgb; \n"
+ " ALPHA = albedo.a; \n"
+ "}");
+
+ border_mat->set_shader(border_shader);
+ border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0));
+
+ rotate_gizmo[3] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ rotate_gizmo[3]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays);
+ rotate_gizmo[3]->surface_set_material(0, border_mat);
+ }
}
// Scale
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 6a8af38742..b3dc4ef5f2 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -412,7 +412,7 @@ private:
real_t zoom_indicator_delay;
- RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3], scale_plane_gizmo_instance[3];
+ RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3];
String last_message;
String message;
@@ -600,11 +600,13 @@ private:
bool grid_enable[3]; //should be always visible if true
bool grid_enabled;
- Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3], scale_plane_gizmo[3];
+ Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3];
Ref<StandardMaterial3D> gizmo_color[3];
Ref<StandardMaterial3D> plane_gizmo_color[3];
+ Ref<ShaderMaterial> rotate_gizmo_color[3];
Ref<StandardMaterial3D> gizmo_color_hl[3];
Ref<StandardMaterial3D> plane_gizmo_color_hl[3];
+ Ref<ShaderMaterial> rotate_gizmo_color_hl[3];
int over_gizmo_handle;
float snap_translate_value;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 20eef1cebd..be8ddf789b 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1585,15 +1585,14 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
continue;
}
- List<int> bpoints;
- se->get_breakpoints(&bpoints);
String base = script->get_path();
if (base.begins_with("local://") || base == "") {
continue;
}
- for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
- p_breakpoints->push_back(base + ":" + itos(E->get() + 1));
+ Array bpoints = se->get_breakpoints();
+ for (int j = 0; j < bpoints.size(); j++) {
+ p_breakpoints->push_back(base + ":" + itos((int)bpoints[j] + 1));
}
}
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 1234ebd267..c2b0b458eb 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -151,7 +151,7 @@ public:
virtual void ensure_focus() = 0;
virtual void tag_saved_version() = 0;
virtual void reload(bool p_soft) {}
- virtual void get_breakpoints(List<int> *p_breakpoints) = 0;
+ virtual Array get_breakpoints() = 0;
virtual void add_callback(const String &p_function, PackedStringArray p_args) = 0;
virtual void update_settings() = 0;
virtual void set_debugger_active(bool p_active) = 0;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4b89ca1216..7feb7cb3d3 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -111,7 +111,7 @@ ConnectionInfoDialog::ConnectionInfoDialog() {
Vector<String> ScriptTextEditor::get_functions() {
String errortxt;
int line = -1, col;
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
String text = te->get_text();
List<String> fnc;
@@ -130,9 +130,9 @@ void ScriptTextEditor::apply_code() {
if (script.is_null()) {
return;
}
- script->set_source_code(code_editor->get_text_edit()->get_text());
+ script->set_source_code(code_editor->get_text_editor()->get_text());
script->update_exports();
- code_editor->get_text_edit()->get_syntax_highlighter()->update_cache();
+ code_editor->get_text_editor()->get_syntax_highlighter()->update_cache();
}
RES ScriptTextEditor::get_edited_resource() const {
@@ -145,9 +145,9 @@ void ScriptTextEditor::set_edited_resource(const RES &p_res) {
script = p_res;
- code_editor->get_text_edit()->set_text(script->get_source_code());
- code_editor->get_text_edit()->clear_undo_history();
- code_editor->get_text_edit()->tag_saved_version();
+ code_editor->get_text_editor()->set_text(script->get_source_code());
+ code_editor->get_text_editor()->clear_undo_history();
+ code_editor->get_text_editor()->tag_saved_version();
emit_signal("name_changed");
code_editor->update_line_and_column();
@@ -167,9 +167,19 @@ void ScriptTextEditor::enable_editor() {
}
void ScriptTextEditor::_load_theme_settings() {
- TextEdit *text_edit = code_editor->get_text_edit();
+ CodeEdit *text_edit = code_editor->get_text_editor();
text_edit->clear_keywords();
+ Color updated_safe_line_number_color = EDITOR_GET("text_editor/highlighting/safe_line_number_color");
+ if (updated_safe_line_number_color != safe_line_number_color) {
+ safe_line_number_color = updated_safe_line_number_color;
+ for (int i = 0; i < text_edit->get_line_count(); i++) {
+ if (text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) {
+ text_edit->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
+ }
+ }
+ }
+
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color");
Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color");
@@ -178,7 +188,6 @@ void ScriptTextEditor::_load_theme_settings() {
Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color");
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color");
- Color safe_line_number_color = EDITOR_GET("text_editor/highlighting/safe_line_number_color");
Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color");
Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color");
Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color");
@@ -203,7 +212,6 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_theme_color_override("completion_font_color", completion_font_color);
text_edit->add_theme_color_override("font_color", text_color);
text_edit->add_theme_color_override("line_number_color", line_number_color);
- text_edit->add_theme_color_override("safe_line_number_color", safe_line_number_color);
text_edit->add_theme_color_override("caret_color", caret_color);
text_edit->add_theme_color_override("caret_background_color", caret_background_color);
text_edit->add_theme_color_override("font_color_selected", text_selected_color);
@@ -233,7 +241,7 @@ void ScriptTextEditor::_set_theme_for_script() {
return;
}
- TextEdit *text_edit = code_editor->get_text_edit();
+ CodeEdit *text_edit = code_editor->get_text_editor();
text_edit->get_syntax_highlighter()->update_cache();
/* add keywords for auto completion */
@@ -284,10 +292,10 @@ void ScriptTextEditor::_show_warnings_panel(bool p_show) {
void ScriptTextEditor::_warning_clicked(Variant p_line) {
if (p_line.get_type() == Variant::INT) {
- code_editor->get_text_edit()->cursor_set_line(p_line.operator int64_t());
+ code_editor->get_text_editor()->cursor_set_line(p_line.operator int64_t());
} else if (p_line.get_type() == Variant::DICTIONARY) {
Dictionary meta = p_line.operator Dictionary();
- code_editor->get_text_edit()->insert_at("# warning-ignore:" + meta["code"].operator String(), meta["line"].operator int64_t() - 1);
+ code_editor->get_text_editor()->insert_at("# warning-ignore:" + meta["code"].operator String(), meta["line"].operator int64_t() - 1);
_validate_script();
}
}
@@ -295,7 +303,7 @@ void ScriptTextEditor::_warning_clicked(Variant p_line) {
void ScriptTextEditor::reload_text() {
ERR_FAIL_COND(script.is_null());
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
int column = te->cursor_get_column();
int row = te->cursor_get_line();
int h = te->get_h_scroll();
@@ -313,20 +321,20 @@ void ScriptTextEditor::reload_text() {
}
void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) {
- String code = code_editor->get_text_edit()->get_text();
+ String code = code_editor->get_text_editor()->get_text();
int pos = script->get_language()->find_function(p_function, code);
if (pos == -1) {
//does not exist
- code_editor->get_text_edit()->deselect();
- pos = code_editor->get_text_edit()->get_line_count() + 2;
+ code_editor->get_text_editor()->deselect();
+ pos = code_editor->get_text_editor()->get_line_count() + 2;
String func = script->get_language()->make_function("", p_function, p_args);
//code=code+func;
- code_editor->get_text_edit()->cursor_set_line(pos + 1);
- code_editor->get_text_edit()->cursor_set_column(1000000); //none shall be that big
- code_editor->get_text_edit()->insert_text_at_cursor("\n\n" + func);
+ code_editor->get_text_editor()->cursor_set_line(pos + 1);
+ code_editor->get_text_editor()->cursor_set_column(1000000); //none shall be that big
+ code_editor->get_text_editor()->insert_text_at_cursor("\n\n" + func);
}
- code_editor->get_text_edit()->cursor_set_line(pos);
- code_editor->get_text_edit()->cursor_set_column(1);
+ code_editor->get_text_editor()->cursor_set_line(pos);
+ code_editor->get_text_editor()->cursor_set_column(1);
}
bool ScriptTextEditor::show_members_overview() {
@@ -334,12 +342,13 @@ bool ScriptTextEditor::show_members_overview() {
}
void ScriptTextEditor::update_settings() {
+ code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EditorSettings::get_singleton()->get("text_editor/appearance/show_info_gutter"));
code_editor->update_editor_settings();
}
bool ScriptTextEditor::is_unsaved() {
const bool unsaved =
- code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version() ||
+ code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() ||
script->get_path().empty(); // In memory.
return unsaved;
}
@@ -385,7 +394,7 @@ void ScriptTextEditor::convert_indent_to_tabs() {
}
void ScriptTextEditor::tag_saved_version() {
- code_editor->get_text_edit()->tag_saved_version();
+ code_editor->get_text_editor()->tag_saved_version();
}
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
@@ -409,7 +418,7 @@ void ScriptTextEditor::clear_executing_line() {
}
void ScriptTextEditor::ensure_focus() {
- code_editor->get_text_edit()->grab_focus();
+ code_editor->get_text_editor()->grab_focus();
}
String ScriptTextEditor::get_name() {
@@ -443,7 +452,7 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
void ScriptTextEditor::_validate_script() {
String errortxt;
int line = -1, col;
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
String text = te->get_text();
List<String> fnc;
@@ -540,16 +549,16 @@ void ScriptTextEditor::_validate_script() {
te->set_line_as_marked(i, line == i);
if (highlight_safe) {
if (safe_lines.has(i + 1)) {
- te->set_line_as_safe(i, true);
+ te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
last_is_safe = true;
} else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().empty())) {
- te->set_line_as_safe(i, true);
+ te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
} else {
- te->set_line_as_safe(i, false);
+ te->set_line_gutter_item_color(i, line_number_gutter, default_line_number_color);
last_is_safe = false;
}
} else {
- te->set_line_as_safe(i, false);
+ te->set_line_gutter_item_color(line, 1, default_line_number_color);
}
}
@@ -566,7 +575,7 @@ void ScriptTextEditor::_update_bookmark_list() {
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();
+ Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}
@@ -576,7 +585,7 @@ void ScriptTextEditor::_update_bookmark_list() {
for (int i = 0; i < bookmark_list.size(); i++) {
// Strip edges to remove spaces or tabs.
// Also replace any tabs by spaces, since we can't print tabs in the menu.
- String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).replace("\t", " ").strip_edges();
+ String line = code_editor->get_text_editor()->get_line(bookmark_list[i]).replace("\t", " ").strip_edges();
// Limit the size of the line if too big.
if (line.length() > 50) {
@@ -593,7 +602,7 @@ void ScriptTextEditor::_bookmark_item_pressed(int p_idx) {
_edit_option(bookmarks_menu->get_item_id(p_idx));
} else {
code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx));
- code_editor->get_text_edit()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred().
+ code_editor->get_text_editor()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred().
}
}
@@ -704,7 +713,7 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
String hint;
Error err = script->get_language()->complete_code(p_code, script->get_path(), base, r_options, r_force, hint);
if (err == OK) {
- code_editor->get_text_edit()->set_code_hint(hint);
+ code_editor->get_text_editor()->set_code_hint(hint);
}
}
@@ -717,7 +726,7 @@ void ScriptTextEditor::_update_breakpoint_list() {
breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT);
breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT);
- Array breakpoint_list = code_editor->get_text_edit()->get_breakpoints_array();
+ Array breakpoint_list = code_editor->get_text_editor()->get_breakpointed_lines();
if (breakpoint_list.size() == 0) {
return;
}
@@ -727,7 +736,7 @@ void ScriptTextEditor::_update_breakpoint_list() {
for (int i = 0; i < breakpoint_list.size(); i++) {
// Strip edges to remove spaces or tabs.
// Also replace any tabs by spaces, since we can't print tabs in the menu.
- String line = code_editor->get_text_edit()->get_line(breakpoint_list[i]).replace("\t", " ").strip_edges();
+ String line = code_editor->get_text_editor()->get_line(breakpoint_list[i]).replace("\t", " ").strip_edges();
// Limit the size of the line if too big.
if (line.length() > 50) {
@@ -744,12 +753,12 @@ void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) {
_edit_option(breakpoints_menu->get_item_id(p_idx));
} else {
code_editor->goto_line(breakpoints_menu->get_item_metadata(p_idx));
- code_editor->get_text_edit()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred().
+ code_editor->get_text_editor()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred().
}
}
void ScriptTextEditor::_breakpoint_toggled(int p_row) {
- EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row));
+ EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_editor()->is_line_breakpointed(p_row));
}
void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
@@ -771,7 +780,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
EditorNode::get_singleton()->load_resource(p_symbol);
}
- } else if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) {
+ } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) {
_goto_line(p_row);
result.class_name = result.class_name.trim_prefix("_");
@@ -866,7 +875,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
}
void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
- TextEdit *text_edit = code_editor->get_text_edit();
+ CodeEdit *text_edit = code_editor->get_text_editor();
Node *base = get_tree()->get_edited_scene_root();
if (base) {
@@ -874,7 +883,7 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
}
ScriptLanguage::LookupResult result;
- if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) {
+ if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) {
text_edit->set_highlighted_word(p_symbol);
} else if (p_symbol.is_rel_path()) {
String path = _get_absolute_path(p_symbol);
@@ -902,8 +911,15 @@ void ScriptTextEditor::update_toggle_scripts_button() {
}
void ScriptTextEditor::_update_connected_methods() {
- TextEdit *text_edit = code_editor->get_text_edit();
- text_edit->clear_info_icons();
+ CodeEdit *text_edit = code_editor->get_text_editor();
+ for (int i = 0; i < text_edit->get_line_count(); i++) {
+ if (text_edit->get_line_gutter_metadata(i, connection_gutter) == "") {
+ continue;
+ }
+ text_edit->set_line_gutter_metadata(i, connection_gutter, "");
+ text_edit->set_line_gutter_icon(i, connection_gutter, nullptr);
+ text_edit->set_line_gutter_clickable(i, connection_gutter, false);
+ }
missing_connections.clear();
if (!script_is_valid) {
@@ -943,8 +959,10 @@ void ScriptTextEditor::_update_connected_methods() {
for (int j = 0; j < functions.size(); j++) {
String name = functions[j].get_slice(":", 0);
if (name == connection.callable.get_method()) {
- line = functions[j].get_slice(":", 1).to_int();
- text_edit->set_line_info_icon(line - 1, get_parent_control()->get_theme_icon("Slot", "EditorIcons"), connection.callable.get_method());
+ line = functions[j].get_slice(":", 1).to_int() - 1;
+ text_edit->set_line_gutter_metadata(line, connection_gutter, connection.callable.get_method());
+ text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon("Slot", "EditorIcons"));
+ text_edit->set_line_gutter_clickable(line, connection_gutter, true);
methods_found.insert(connection.callable.get_method());
break;
}
@@ -974,18 +992,41 @@ void ScriptTextEditor::_update_connected_methods() {
}
}
-void ScriptTextEditor::_lookup_connections(int p_row, String p_method) {
+void ScriptTextEditor::_update_gutter_indexes() {
+ for (int i = 0; i < code_editor->get_text_editor()->get_gutter_count(); i++) {
+ if (code_editor->get_text_editor()->get_gutter_name(i) == "connection_gutter") {
+ connection_gutter = i;
+ continue;
+ }
+
+ if (code_editor->get_text_editor()->get_gutter_name(i) == "line_numbers") {
+ line_number_gutter = i;
+ continue;
+ }
+ }
+}
+
+void ScriptTextEditor::_gutter_clicked(int p_line, int p_gutter) {
+ if (p_gutter != connection_gutter) {
+ return;
+ }
+
+ String method = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter);
+ if (method == "") {
+ return;
+ }
+
Node *base = get_tree()->get_edited_scene_root();
if (!base) {
return;
}
Vector<Node *> nodes = _find_all_node_for_script(base, base, script);
- connection_info_dialog->popup_connections(p_method, nodes);
+ connection_info_dialog->popup_connections(method, nodes);
}
void ScriptTextEditor::_edit_option(int p_op) {
- TextEdit *tx = code_editor->get_text_edit();
+ CodeEdit *tx = code_editor->get_text_editor();
switch (p_op) {
case EDIT_UNDO: {
@@ -1109,7 +1150,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_EVALUATE: {
Expression expression;
- Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
+ Vector<String> lines = code_editor->get_text_editor()->get_selection_text().split("\n");
PackedStringArray results;
for (int i = 0; i < lines.size(); i++) {
@@ -1128,9 +1169,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
}
- code_editor->get_text_edit()->begin_complex_operation(); //prevents creating a two-step undo
- code_editor->get_text_edit()->insert_text_at_cursor(String("\n").join(results));
- code_editor->get_text_edit()->end_complex_operation();
+ code_editor->get_text_editor()->begin_complex_operation(); //prevents creating a two-step undo
+ code_editor->get_text_editor()->insert_text_at_cursor(String("\n").join(results));
+ code_editor->get_text_editor()->end_complex_operation();
} break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1145,14 +1186,14 @@ void ScriptTextEditor::_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();
+ String selected_text = code_editor->get_text_editor()->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 REPLACE_IN_FILES: {
- String selected_text = code_editor->get_text_edit()->get_selection_text();
+ String selected_text = code_editor->get_text_editor()->get_selection_text();
emit_signal("replace_in_files_requested", selected_text);
} break;
@@ -1177,24 +1218,22 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case DEBUG_TOGGLE_BREAKPOINT: {
int line = tx->cursor_get_line();
- bool dobreak = !tx->is_line_set_as_breakpoint(line);
+ bool dobreak = !tx->is_line_breakpointed(line);
tx->set_line_as_breakpoint(line, dobreak);
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
} break;
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
- List<int> bpoints;
- tx->get_breakpoints(&bpoints);
+ Array bpoints = tx->get_breakpointed_lines();
- for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
- int line = E->get();
- bool dobreak = !tx->is_line_set_as_breakpoint(line);
+ for (int i = 0; i < bpoints.size(); i++) {
+ int line = bpoints[i];
+ bool dobreak = !tx->is_line_breakpointed(line);
tx->set_line_as_breakpoint(line, dobreak);
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
}
} break;
case DEBUG_GOTO_NEXT_BREAKPOINT: {
- List<int> bpoints;
- tx->get_breakpoints(&bpoints);
+ Array bpoints = tx->get_breakpointed_lines();
if (bpoints.size() <= 0) {
return;
}
@@ -1202,13 +1241,13 @@ void ScriptTextEditor::_edit_option(int p_op) {
int line = tx->cursor_get_line();
// wrap around
- if (line >= bpoints[bpoints.size() - 1]) {
+ if (line >= (int)bpoints[bpoints.size() - 1]) {
tx->unfold_line(bpoints[0]);
tx->cursor_set_line(bpoints[0]);
tx->center_viewport_to_cursor();
} else {
- for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
- int bline = E->get();
+ for (int i = 0; i < bpoints.size(); i++) {
+ int bline = bpoints[i];
if (bline > line) {
tx->unfold_line(bline);
tx->cursor_set_line(bline);
@@ -1220,21 +1259,20 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case DEBUG_GOTO_PREV_BREAKPOINT: {
- List<int> bpoints;
- tx->get_breakpoints(&bpoints);
+ Array bpoints = tx->get_breakpointed_lines();
if (bpoints.size() <= 0) {
return;
}
int line = tx->cursor_get_line();
// wrap around
- if (line <= bpoints[0]) {
+ if (line <= (int)bpoints[0]) {
tx->unfold_line(bpoints[bpoints.size() - 1]);
tx->cursor_set_line(bpoints[bpoints.size() - 1]);
tx->center_viewport_to_cursor();
} else {
- for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) {
- int bline = E->get();
+ for (int i = bpoints.size(); i >= 0; i--) {
+ int bline = bpoints[i];
if (bline < line) {
tx->unfold_line(bline);
tx->cursor_set_line(bline);
@@ -1303,7 +1341,7 @@ void ScriptTextEditor::set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_hig
el = el->next();
}
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
p_highlighter->_set_edited_resource(script);
te->set_syntax_highlighter(p_highlighter);
}
@@ -1312,6 +1350,16 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
}
+void ScriptTextEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ code_editor->get_text_editor()->set_gutter_width(connection_gutter, code_editor->get_text_editor()->get_row_height());
+ } break;
+ default:
+ break;
+ }
+}
+
void ScriptTextEditor::_bind_methods() {
ClassDB::bind_method("_update_connected_methods", &ScriptTextEditor::_update_connected_methods);
@@ -1331,7 +1379,7 @@ void ScriptTextEditor::clear_edit_menu() {
}
void ScriptTextEditor::reload(bool p_soft) {
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
Ref<Script> scr = script;
if (scr.is_null()) {
return;
@@ -1342,12 +1390,12 @@ void ScriptTextEditor::reload(bool p_soft) {
scr->get_language()->reload_tool_script(scr, soft);
}
-void ScriptTextEditor::get_breakpoints(List<int> *p_breakpoints) {
- code_editor->get_text_edit()->get_breakpoints(p_breakpoints);
+Array ScriptTextEditor::get_breakpoints() {
+ return code_editor->get_text_editor()->get_breakpointed_lines();
}
void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
- code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
+ code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this);
}
void ScriptTextEditor::set_debugger_active(bool p_active) {
@@ -1393,7 +1441,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
Dictionary d = p_data;
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
int row, col;
te->_get_mouse_pos(p_point, row, col);
@@ -1466,7 +1514,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
Point2 local_pos;
bool create_menu = false;
- TextEdit *tx = code_editor->get_text_edit();
+ CodeEdit *tx = code_editor->get_text_editor();
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;
@@ -1519,7 +1567,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
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) {
+ if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), word_at_pos, script->get_path(), base, result) == OK) {
open_docs = true;
}
}
@@ -1567,17 +1615,17 @@ 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_position.x);
+ String line = code_editor->get_text_editor()->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()->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();
+ code_editor->get_text_editor()->begin_complex_operation();
+ code_editor->get_text_editor()->set_line(color_position.x, line_with_replaced_args);
+ code_editor->get_text_editor()->end_complex_operation();
+ code_editor->get_text_editor()->update();
}
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) {
@@ -1636,12 +1684,15 @@ void ScriptTextEditor::_enable_code_editor() {
code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel));
code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script));
code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings));
- code_editor->get_text_edit()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
- code_editor->get_text_edit()->connect("symbol_lookup", callable_mp(this, &ScriptTextEditor::_lookup_symbol));
- code_editor->get_text_edit()->connect("symbol_validate", callable_mp(this, &ScriptTextEditor::_validate_symbol));
- code_editor->get_text_edit()->connect("info_clicked", callable_mp(this, &ScriptTextEditor::_lookup_connections));
- code_editor->get_text_edit()->connect("gui_input", callable_mp(this, &ScriptTextEditor::_text_edit_gui_input));
+ code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
+ code_editor->get_text_editor()->connect("symbol_lookup", callable_mp(this, &ScriptTextEditor::_lookup_symbol));
+ code_editor->get_text_editor()->connect("symbol_validate", callable_mp(this, &ScriptTextEditor::_validate_symbol));
+ code_editor->get_text_editor()->connect("gutter_added", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
+ code_editor->get_text_editor()->connect("gutter_removed", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
+ code_editor->get_text_editor()->connect("gutter_clicked", callable_mp(this, &ScriptTextEditor::_gutter_clicked));
+ code_editor->get_text_editor()->connect("gui_input", callable_mp(this, &ScriptTextEditor::_text_edit_gui_input));
code_editor->show_toggle_scripts_button();
+ _update_gutter_indexes();
editor_box->add_child(warnings_panel);
warnings_panel->add_theme_font_override(
@@ -1758,6 +1809,16 @@ ScriptTextEditor::ScriptTextEditor() {
code_editor->set_code_complete_func(_code_complete_scripts, this);
code_editor->set_v_size_flags(SIZE_EXPAND_FILL);
+ code_editor->get_text_editor()->set_draw_breakpoints_gutter(true);
+ code_editor->get_text_editor()->set_draw_executing_lines_gutter(true);
+
+ connection_gutter = 1;
+ code_editor->get_text_editor()->add_gutter(connection_gutter);
+ code_editor->get_text_editor()->set_gutter_name(connection_gutter, "connection_gutter");
+ code_editor->get_text_editor()->set_gutter_draw(connection_gutter, false);
+ code_editor->get_text_editor()->set_gutter_overwritable(connection_gutter, true);
+ code_editor->get_text_editor()->set_gutter_type(connection_gutter, TextEdit::GUTTER_TPYE_ICON);
+
warnings_panel = memnew(RichTextLabel);
warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE));
warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1768,12 +1829,12 @@ ScriptTextEditor::ScriptTextEditor() {
update_settings();
- code_editor->get_text_edit()->set_callhint_settings(
+ code_editor->get_text_editor()->set_callhint_settings(
EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"),
EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset"));
- code_editor->get_text_edit()->set_select_identifiers_on_hover(true);
- code_editor->get_text_edit()->set_context_menu_enabled(false);
+ code_editor->get_text_editor()->set_select_identifiers_on_hover(true);
+ code_editor->get_text_editor()->set_context_menu_enabled(false);
context_menu = memnew(PopupMenu);
@@ -1816,7 +1877,7 @@ ScriptTextEditor::ScriptTextEditor() {
connection_info_dialog = memnew(ConnectionInfoDialog);
- code_editor->get_text_edit()->set_drag_forwarding(this);
+ code_editor->get_text_editor()->set_drag_forwarding(this);
}
ScriptTextEditor::~ScriptTextEditor() {
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index e931c9fdc6..1e436fbe65 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -81,6 +81,14 @@ class ScriptTextEditor : public ScriptEditorBase {
ScriptEditorQuickOpen *quick_open = nullptr;
ConnectionInfoDialog *connection_info_dialog = nullptr;
+ int connection_gutter = -1;
+ void _gutter_clicked(int p_line, int p_gutter);
+ void _update_gutter_indexes();
+
+ int line_number_gutter = -1;
+ Color default_line_number_color = Color(1, 1, 1);
+ Color safe_line_number_color = Color(1, 1, 1);
+
PopupPanel *color_panel = nullptr;
ColorPicker *color_picker = nullptr;
Vector2 color_position;
@@ -154,6 +162,7 @@ protected:
void _show_warnings_panel(bool p_show);
void _warning_clicked(Variant p_line);
+ void _notification(int p_what);
static void _bind_methods();
Map<String, Ref<EditorSyntaxHighlighter>> highlighters;
@@ -169,8 +178,6 @@ protected:
void _lookup_symbol(const String &p_symbol, int p_row, int p_column);
void _validate_symbol(const String &p_symbol);
- void _lookup_connections(int p_row, String p_method);
-
void _convert_case(CodeTextEditor::CaseStyle p_case);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
@@ -211,7 +218,7 @@ public:
virtual void clear_executing_line() override;
virtual void reload(bool p_soft) override;
- virtual void get_breakpoints(List<int> *p_breakpoints) override;
+ virtual Array get_breakpoints() override;
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 2a7f3f0656..29db284b44 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -55,8 +55,8 @@ 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();
+ get_text_editor()->set_text(p_shader->get_code());
+ get_text_editor()->clear_undo_history();
_validate_script();
_line_col_changed();
@@ -65,7 +65,7 @@ void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) {
void ShaderTextEditor::reload_text() {
ERR_FAIL_COND(shader.is_null());
- TextEdit *te = get_text_edit();
+ CodeEdit *te = get_text_editor();
int column = te->cursor_get_column();
int row = te->cursor_get_line();
int h = te->get_h_scroll();
@@ -107,29 +107,29 @@ void ShaderTextEditor::_load_theme_settings() {
Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color");
Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color");
- get_text_edit()->add_theme_color_override("background_color", background_color);
- get_text_edit()->add_theme_color_override("completion_background_color", completion_background_color);
- get_text_edit()->add_theme_color_override("completion_selected_color", completion_selected_color);
- get_text_edit()->add_theme_color_override("completion_existing_color", completion_existing_color);
- get_text_edit()->add_theme_color_override("completion_scroll_color", completion_scroll_color);
- get_text_edit()->add_theme_color_override("completion_font_color", completion_font_color);
- get_text_edit()->add_theme_color_override("font_color", text_color);
- get_text_edit()->add_theme_color_override("line_number_color", line_number_color);
- get_text_edit()->add_theme_color_override("caret_color", caret_color);
- get_text_edit()->add_theme_color_override("caret_background_color", caret_background_color);
- get_text_edit()->add_theme_color_override("font_color_selected", text_selected_color);
- get_text_edit()->add_theme_color_override("selection_color", selection_color);
- get_text_edit()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color);
- get_text_edit()->add_theme_color_override("current_line_color", current_line_color);
- get_text_edit()->add_theme_color_override("line_length_guideline_color", line_length_guideline_color);
- get_text_edit()->add_theme_color_override("word_highlighted_color", word_highlighted_color);
- get_text_edit()->add_theme_color_override("mark_color", mark_color);
- get_text_edit()->add_theme_color_override("bookmark_color", bookmark_color);
- get_text_edit()->add_theme_color_override("breakpoint_color", breakpoint_color);
- get_text_edit()->add_theme_color_override("executing_line_color", executing_line_color);
- get_text_edit()->add_theme_color_override("code_folding_color", code_folding_color);
- get_text_edit()->add_theme_color_override("search_result_color", search_result_color);
- get_text_edit()->add_theme_color_override("search_result_border_color", search_result_border_color);
+ get_text_editor()->add_theme_color_override("background_color", background_color);
+ get_text_editor()->add_theme_color_override("completion_background_color", completion_background_color);
+ get_text_editor()->add_theme_color_override("completion_selected_color", completion_selected_color);
+ get_text_editor()->add_theme_color_override("completion_existing_color", completion_existing_color);
+ get_text_editor()->add_theme_color_override("completion_scroll_color", completion_scroll_color);
+ get_text_editor()->add_theme_color_override("completion_font_color", completion_font_color);
+ get_text_editor()->add_theme_color_override("font_color", text_color);
+ get_text_editor()->add_theme_color_override("line_number_color", line_number_color);
+ get_text_editor()->add_theme_color_override("caret_color", caret_color);
+ get_text_editor()->add_theme_color_override("caret_background_color", caret_background_color);
+ get_text_editor()->add_theme_color_override("font_color_selected", text_selected_color);
+ get_text_editor()->add_theme_color_override("selection_color", selection_color);
+ get_text_editor()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color);
+ get_text_editor()->add_theme_color_override("current_line_color", current_line_color);
+ get_text_editor()->add_theme_color_override("line_length_guideline_color", line_length_guideline_color);
+ get_text_editor()->add_theme_color_override("word_highlighted_color", word_highlighted_color);
+ get_text_editor()->add_theme_color_override("mark_color", mark_color);
+ get_text_editor()->add_theme_color_override("bookmark_color", bookmark_color);
+ get_text_editor()->add_theme_color_override("breakpoint_color", breakpoint_color);
+ get_text_editor()->add_theme_color_override("executing_line_color", executing_line_color);
+ get_text_editor()->add_theme_color_override("code_folding_color", code_folding_color);
+ get_text_editor()->add_theme_color_override("search_result_color", search_result_color);
+ get_text_editor()->add_theme_color_override("search_result_border_color", search_result_border_color);
syntax_highlighter->set_number_color(EDITOR_GET("text_editor/highlighting/number_color"));
syntax_highlighter->set_symbol_color(EDITOR_GET("text_editor/highlighting/symbol_color"));
@@ -176,7 +176,7 @@ void ShaderTextEditor::_load_theme_settings() {
}
void ShaderTextEditor::_check_shader_mode() {
- String type = ShaderLanguage::get_shader_type(get_text_edit()->get_text());
+ String type = ShaderLanguage::get_shader_type(get_text_editor()->get_text());
Shader::Mode mode;
@@ -189,7 +189,7 @@ void ShaderTextEditor::_check_shader_mode() {
}
if (shader->get_mode() != mode) {
- shader->set_code(get_text_edit()->get_text());
+ shader->set_code(get_text_editor()->get_text());
_load_theme_settings();
}
}
@@ -207,13 +207,13 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip);
- get_text_edit()->set_code_hint(calltip);
+ get_text_editor()->set_code_hint(calltip);
}
void ShaderTextEditor::_validate_script() {
_check_shader_mode();
- String code = get_text_edit()->get_text();
+ String code = get_text_editor()->get_text();
//List<StringName> params;
//shader->get_param_list(&params);
@@ -225,14 +225,14 @@ void ShaderTextEditor::_validate_script() {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
set_error(error_text);
set_error_pos(sl.get_error_line() - 1, 0);
- for (int i = 0; i < get_text_edit()->get_line_count(); i++) {
- get_text_edit()->set_line_as_marked(i, false);
+ for (int i = 0; i < get_text_editor()->get_line_count(); i++) {
+ get_text_editor()->set_line_as_marked(i, false);
}
- get_text_edit()->set_line_as_marked(sl.get_error_line() - 1, true);
+ get_text_editor()->set_line_as_marked(sl.get_error_line() - 1, true);
} else {
- for (int i = 0; i < get_text_edit()->get_line_count(); i++) {
- get_text_edit()->set_line_as_marked(i, false);
+ for (int i = 0; i < get_text_editor()->get_line_count(); i++) {
+ get_text_editor()->set_line_as_marked(i, false);
}
set_error("");
}
@@ -245,7 +245,7 @@ void ShaderTextEditor::_bind_methods() {
ShaderTextEditor::ShaderTextEditor() {
syntax_highlighter.instance();
- get_text_edit()->set_syntax_highlighter(syntax_highlighter);
+ get_text_editor()->set_syntax_highlighter(syntax_highlighter);
}
/*** SCRIPT EDITOR ******/
@@ -253,22 +253,22 @@ ShaderTextEditor::ShaderTextEditor() {
void ShaderEditor::_menu_option(int p_option) {
switch (p_option) {
case EDIT_UNDO: {
- shader_editor->get_text_edit()->undo();
+ shader_editor->get_text_editor()->undo();
} break;
case EDIT_REDO: {
- shader_editor->get_text_edit()->redo();
+ shader_editor->get_text_editor()->redo();
} break;
case EDIT_CUT: {
- shader_editor->get_text_edit()->cut();
+ shader_editor->get_text_editor()->cut();
} break;
case EDIT_COPY: {
- shader_editor->get_text_edit()->copy();
+ shader_editor->get_text_editor()->copy();
} break;
case EDIT_PASTE: {
- shader_editor->get_text_edit()->paste();
+ shader_editor->get_text_editor()->paste();
} break;
case EDIT_SELECT_ALL: {
- shader_editor->get_text_edit()->select_all();
+ shader_editor->get_text_editor()->select_all();
} break;
case EDIT_MOVE_LINE_UP: {
shader_editor->move_lines_up();
@@ -281,7 +281,7 @@ void ShaderEditor::_menu_option(int p_option) {
return;
}
- TextEdit *tx = shader_editor->get_text_edit();
+ CodeEdit *tx = shader_editor->get_text_editor();
tx->indent_left();
} break;
@@ -290,7 +290,7 @@ void ShaderEditor::_menu_option(int p_option) {
return;
}
- TextEdit *tx = shader_editor->get_text_edit();
+ CodeEdit *tx = shader_editor->get_text_editor();
tx->indent_right();
} break;
@@ -309,7 +309,7 @@ void ShaderEditor::_menu_option(int p_option) {
} break;
case EDIT_COMPLETE: {
- shader_editor->get_text_edit()->query_code_comple();
+ shader_editor->get_text_editor()->query_code_comple();
} break;
case SEARCH_FIND: {
shader_editor->get_find_replace_bar()->popup_search();
@@ -324,7 +324,7 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->get_find_replace_bar()->popup_replace();
} break;
case SEARCH_GOTO_LINE: {
- goto_line_dialog->popup_find_line(shader_editor->get_text_edit());
+ goto_line_dialog->popup_find_line(shader_editor->get_text_editor());
} break;
case BOOKMARK_TOGGLE: {
shader_editor->toggle_bookmark();
@@ -343,7 +343,7 @@ void ShaderEditor::_menu_option(int p_option) {
} break;
}
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
- shader_editor->get_text_edit()->call_deferred("grab_focus");
+ shader_editor->get_text_editor()->call_deferred("grab_focus");
}
}
@@ -358,28 +358,11 @@ void ShaderEditor::_params_changed() {
}
void ShaderEditor::_editor_settings_changed() {
- shader_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
- shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
- shader_editor->get_text_edit()->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
- 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_draw_spaces(EditorSettings::get_singleton()->get("text_editor/indent/draw_spaces"));
- 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_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"));
- shader_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
- 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_theme_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/navigation/smooth_scrolling"));
- shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/navigation/v_scroll_speed"));
- shader_editor->get_text_edit()->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/navigation/show_minimap"));
- shader_editor->get_text_edit()->set_minimap_width((int)EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width") * EDSCALE);
- shader_editor->get_text_edit()->set_show_line_length_guidelines(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guidelines"));
- shader_editor->get_text_edit()->set_line_length_guideline_soft_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_soft_column"));
- shader_editor->get_text_edit()->set_line_length_guideline_hard_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_hard_column"));
- shader_editor->get_text_edit()->set_breakpoint_gutter_enabled(false);
+ shader_editor->update_editor_settings();
+
+ shader_editor->get_text_editor()->add_theme_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing"));
+ shader_editor->get_text_editor()->set_draw_breakpoints_gutter(false);
+ shader_editor->get_text_editor()->set_draw_executing_lines_gutter(false);
}
void ShaderEditor::_bind_methods() {
@@ -466,7 +449,7 @@ void ShaderEditor::save_external_data(const String &p_str) {
void ShaderEditor::apply_shaders() {
if (shader.is_valid()) {
String shader_code = shader->get_code();
- String editor_code = shader_editor->get_text_edit()->get_text();
+ String editor_code = shader_editor->get_text_editor()->get_text();
if (shader_code != editor_code) {
shader->set_code(editor_code);
shader->set_edited(true);
@@ -480,7 +463,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
int col, row;
- TextEdit *tx = shader_editor->get_text_edit();
+ CodeEdit *tx = shader_editor->get_text_editor();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
@@ -507,7 +490,7 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
Ref<InputEventKey> k = ev;
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_MENU) {
- TextEdit *tx = shader_editor->get_text_edit();
+ CodeEdit *tx = shader_editor->get_text_editor();
_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();
}
@@ -521,7 +504,7 @@ void ShaderEditor::_update_bookmark_list() {
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();
+ Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}
@@ -529,7 +512,7 @@ void ShaderEditor::_update_bookmark_list() {
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();
+ String line = shader_editor->get_text_editor()->get_line(bookmark_list[i]).strip_edges();
// Limit the size of the line if too big.
if (line.length() > 50) {
line = line.substr(0, 50);
@@ -581,13 +564,13 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
shader_editor->connect("script_changed", callable_mp(this, &ShaderEditor::apply_shaders));
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ShaderEditor::_editor_settings_changed));
- shader_editor->get_text_edit()->set_callhint_settings(
+ shader_editor->get_text_editor()->set_callhint_settings(
EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"),
EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset"));
- shader_editor->get_text_edit()->set_select_identifiers_on_hover(true);
- shader_editor->get_text_edit()->set_context_menu_enabled(false);
- shader_editor->get_text_edit()->connect("gui_input", callable_mp(this, &ShaderEditor::_text_edit_gui_input));
+ shader_editor->get_text_editor()->set_select_identifiers_on_hover(true);
+ shader_editor->get_text_editor()->set_context_menu_enabled(false);
+ shader_editor->get_text_editor()->connect("gui_input", callable_mp(this, &ShaderEditor::_text_edit_gui_input));
shader_editor->update_editor_settings();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 18942b371c..5007983581 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -995,11 +995,16 @@ SpriteFramesEditor::SpriteFramesEditor() {
animations->connect("item_edited", callable_mp(this, &SpriteFramesEditor::_animation_name_edited));
animations->set_allow_reselect(true);
+ HBoxContainer *hbc_anim_speed = memnew(HBoxContainer);
+ hbc_anim_speed->add_child(memnew(Label(TTR("Speed:"))));
+ vbc_animlist->add_child(hbc_anim_speed);
anim_speed = memnew(SpinBox);
- vbc_animlist->add_margin_child(TTR("Speed (FPS):"), anim_speed);
+ anim_speed->set_suffix(TTR("FPS"));
anim_speed->set_min(0);
anim_speed->set_max(100);
anim_speed->set_step(0.01);
+ anim_speed->set_h_size_flags(SIZE_EXPAND_FILL);
+ hbc_anim_speed->add_child(anim_speed);
anim_speed->connect("value_changed", callable_mp(this, &SpriteFramesEditor::_animation_fps_changed));
anim_loop = memnew(CheckButton);
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 82e231e396..8935b698b6 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -50,7 +50,7 @@ void TextEditor::set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlight
el = el->next();
}
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
te->set_syntax_highlighter(p_highlighter);
}
@@ -59,7 +59,7 @@ void TextEditor::_change_syntax_highlighter(int p_idx) {
}
void TextEditor::_load_theme_settings() {
- TextEdit *text_edit = code_editor->get_text_edit();
+ CodeEdit *text_edit = code_editor->get_text_editor();
text_edit->get_syntax_highlighter()->update_cache();
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
@@ -147,9 +147,9 @@ void TextEditor::set_edited_resource(const RES &p_res) {
text_file = p_res;
- code_editor->get_text_edit()->set_text(text_file->get_text());
- code_editor->get_text_edit()->clear_undo_history();
- code_editor->get_text_edit()->tag_saved_version();
+ code_editor->get_text_editor()->set_text(text_file->get_text());
+ code_editor->get_text_editor()->clear_undo_history();
+ code_editor->get_text_editor()->tag_saved_version();
emit_signal("name_changed");
code_editor->update_line_and_column();
@@ -171,13 +171,14 @@ void TextEditor::add_callback(const String &p_function, PackedStringArray p_args
void TextEditor::set_debugger_active(bool p_active) {
}
-void TextEditor::get_breakpoints(List<int> *p_breakpoints) {
+Array TextEditor::get_breakpoints() {
+ return Array();
}
void TextEditor::reload_text() {
ERR_FAIL_COND(text_file.is_null());
- TextEdit *te = code_editor->get_text_edit();
+ CodeEdit *te = code_editor->get_text_editor();
int column = te->cursor_get_column();
int row = te->cursor_get_line();
int h = te->get_h_scroll();
@@ -207,7 +208,7 @@ void TextEditor::_update_bookmark_list() {
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();
+ Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}
@@ -215,7 +216,7 @@ void TextEditor::_update_bookmark_list() {
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();
+ String line = code_editor->get_text_editor()->get_line(bookmark_list[i]).strip_edges();
// Limit the size of the line if too big.
if (line.length() > 50) {
line = line.substr(0, 50);
@@ -235,12 +236,12 @@ void TextEditor::_bookmark_item_pressed(int p_idx) {
}
void TextEditor::apply_code() {
- text_file->set_text(code_editor->get_text_edit()->get_text());
+ text_file->set_text(code_editor->get_text_editor()->get_text());
}
bool TextEditor::is_unsaved() {
const bool unsaved =
- code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version() ||
+ code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() ||
text_file->get_path().empty(); // In memory.
return unsaved;
}
@@ -280,7 +281,7 @@ void TextEditor::convert_indent_to_tabs() {
}
void TextEditor::tag_saved_version() {
- code_editor->get_text_edit()->tag_saved_version();
+ code_editor->get_text_editor()->tag_saved_version();
}
void TextEditor::goto_line(int p_line, bool p_with_error) {
@@ -300,7 +301,7 @@ void TextEditor::clear_executing_line() {
}
void TextEditor::ensure_focus() {
- code_editor->get_text_edit()->grab_focus();
+ code_editor->get_text_editor()->grab_focus();
}
Vector<String> TextEditor::get_functions() {
@@ -316,7 +317,7 @@ void TextEditor::update_settings() {
}
void TextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
- code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
+ code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this);
}
Control *TextEditor::get_edit_menu() {
@@ -328,7 +329,7 @@ void TextEditor::clear_edit_menu() {
}
void TextEditor::_edit_option(int p_op) {
- TextEdit *tx = code_editor->get_text_edit();
+ CodeEdit *tx = code_editor->get_text_editor();
switch (p_op) {
case EDIT_UNDO: {
@@ -416,14 +417,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();
+ String selected_text = code_editor->get_text_editor()->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 REPLACE_IN_FILES: {
- String selected_text = code_editor->get_text_edit()->get_selection_text();
+ String selected_text = code_editor->get_text_editor()->get_selection_text();
emit_signal("replace_in_files_requested", selected_text);
} break;
@@ -470,7 +471,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_RIGHT) {
int col, row;
- TextEdit *tx = code_editor->get_text_edit();
+ CodeEdit *tx = code_editor->get_text_editor();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
@@ -503,7 +504,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
Ref<InputEventKey> k = ev;
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_MENU) {
- TextEdit *tx = code_editor->get_text_edit();
+ CodeEdit *tx = code_editor->get_text_editor();
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();
@@ -552,8 +553,8 @@ TextEditor::TextEditor() {
update_settings();
- code_editor->get_text_edit()->set_context_menu_enabled(false);
- code_editor->get_text_edit()->connect("gui_input", callable_mp(this, &TextEditor::_text_edit_gui_input));
+ code_editor->get_text_editor()->set_context_menu_enabled(false);
+ code_editor->get_text_editor()->connect("gui_input", callable_mp(this, &TextEditor::_text_edit_gui_input));
context_menu = memnew(PopupMenu);
add_child(context_menu);
@@ -649,7 +650,7 @@ TextEditor::TextEditor() {
goto_line_dialog = memnew(GotoLineDialog);
add_child(goto_line_dialog);
- code_editor->get_text_edit()->set_drag_forwarding(this);
+ code_editor->get_text_editor()->set_drag_forwarding(this);
}
TextEditor::~TextEditor() {
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index f3e9e599cf..ea425bd033 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -119,7 +119,7 @@ public:
virtual Variant get_edit_state() override;
virtual void set_edit_state(const Variant &p_state) override;
virtual Vector<String> get_functions() override;
- virtual void get_breakpoints(List<int> *p_breakpoints) override;
+ virtual Array get_breakpoints() override;
virtual void goto_line(int p_line, bool p_with_error = false) override;
void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line) override;
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
new file mode 100644
index 0000000000..ba2eef8484
--- /dev/null
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -0,0 +1,213 @@
+/*************************************************************************/
+/* texture_3d_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "texture_3d_editor_plugin.h"
+
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
+#include "editor/editor_settings.h"
+
+void Texture3DEditor::_gui_input(Ref<InputEvent> p_event) {
+}
+
+void Texture3DEditor::_texture_rect_draw() {
+ texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1));
+}
+
+void Texture3DEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_READY) {
+ //get_scene()->connect("node_removed",this,"_node_removed");
+ }
+ if (p_what == NOTIFICATION_RESIZED) {
+ _texture_rect_update_area();
+ }
+
+ if (p_what == NOTIFICATION_DRAW) {
+ Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons");
+ Size2 size = get_size();
+
+ draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ }
+}
+
+void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+ if (!is_visible()) {
+ return;
+ }
+ update();
+}
+
+void Texture3DEditor::_update_material() {
+ material->set_shader_param("layer", (layer->get_value() + 0.5) / texture->get_depth());
+ material->set_shader_param("tex", texture->get_rid());
+
+ String format = Image::get_format_name(texture->get_format());
+
+ String text;
+ text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + "x" + itos(texture->get_depth()) + " " + format;
+
+ info->set_text(text);
+}
+
+void Texture3DEditor::_make_shaders() {
+ String shader_3d = ""
+ "shader_type canvas_item;\n"
+ "uniform sampler3D tex;\n"
+ "uniform float layer;\n"
+ "void fragment() {\n"
+ " COLOR = textureLod(tex,vec3(UV,layer),0.0);\n"
+ "}";
+
+ shader.instance();
+ shader->set_code(shader_3d);
+ material.instance();
+ material->set_shader(shader);
+}
+
+void Texture3DEditor::_texture_rect_update_area() {
+ Size2 size = get_size();
+ int tex_width = texture->get_width() * size.height / texture->get_height();
+ int tex_height = size.height;
+
+ if (tex_width > size.width) {
+ tex_width = size.width;
+ tex_height = texture->get_height() * tex_width / texture->get_width();
+ }
+
+ // Prevent the texture from being unpreviewable after the rescale, so that we can still see something
+ if (tex_height <= 0) {
+ tex_height = 1;
+ }
+ if (tex_width <= 0) {
+ tex_width = 1;
+ }
+
+ int ofs_x = (size.width - tex_width) / 2;
+ int ofs_y = (size.height - tex_height) / 2;
+
+ texture_rect->set_position(Vector2(ofs_x, ofs_y));
+ texture_rect->set_size(Vector2(tex_width, tex_height));
+}
+
+void Texture3DEditor::edit(Ref<Texture3D> p_texture) {
+ if (!texture.is_null()) {
+ texture->remove_change_receptor(this);
+ }
+
+ texture = p_texture;
+
+ if (!texture.is_null()) {
+ if (shader.is_null()) {
+ _make_shaders();
+ }
+
+ texture->add_change_receptor(this);
+ update();
+ texture_rect->set_material(material);
+ setting = true;
+ layer->set_max(texture->get_depth() - 1);
+ layer->set_value(0);
+ layer->show();
+ _update_material();
+ setting = false;
+ _texture_rect_update_area();
+ } else {
+ hide();
+ }
+}
+
+void Texture3DEditor::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_gui_input"), &Texture3DEditor::_gui_input);
+ ClassDB::bind_method(D_METHOD("_layer_changed"), &Texture3DEditor::_layer_changed);
+}
+
+Texture3DEditor::Texture3DEditor() {
+ set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED);
+ set_custom_minimum_size(Size2(1, 150));
+ texture_rect = memnew(Control);
+ texture_rect->connect("draw", callable_mp(this, &Texture3DEditor::_texture_rect_draw));
+ texture_rect->set_mouse_filter(MOUSE_FILTER_IGNORE);
+ add_child(texture_rect);
+
+ layer = memnew(SpinBox);
+ layer->set_step(1);
+ layer->set_max(100);
+ add_child(layer);
+ layer->set_anchor(MARGIN_RIGHT, 1);
+ layer->set_anchor(MARGIN_LEFT, 1);
+ layer->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ layer->set_modulate(Color(1, 1, 1, 0.8));
+ info = memnew(Label);
+ add_child(info);
+ info->set_anchor(MARGIN_RIGHT, 1);
+ info->set_anchor(MARGIN_LEFT, 1);
+ info->set_anchor(MARGIN_BOTTOM, 1);
+ info->set_anchor(MARGIN_TOP, 1);
+ info->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ info->set_v_grow_direction(GROW_DIRECTION_BEGIN);
+ info->add_theme_color_override("font_color", Color(1, 1, 1, 1));
+ info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_constant_override("shadow_as_outline", 1);
+ info->add_theme_constant_override("shadow_offset_x", 2);
+ info->add_theme_constant_override("shadow_offset_y", 2);
+
+ setting = false;
+ layer->connect("value_changed", Callable(this, "_layer_changed"));
+}
+
+Texture3DEditor::~Texture3DEditor() {
+ if (!texture.is_null()) {
+ texture->remove_change_receptor(this);
+ }
+}
+
+//
+bool EditorInspectorPlugin3DTexture::can_handle(Object *p_object) {
+ return Object::cast_to<Texture3D>(p_object) != nullptr;
+}
+
+void EditorInspectorPlugin3DTexture::parse_begin(Object *p_object) {
+ Texture3D *texture = Object::cast_to<Texture3D>(p_object);
+ if (!texture) {
+ return;
+ }
+ Ref<Texture3D> m(texture);
+
+ Texture3DEditor *editor = memnew(Texture3DEditor);
+ editor->edit(m);
+ add_custom_control(editor);
+}
+
+Texture3DEditorPlugin::Texture3DEditorPlugin(EditorNode *p_node) {
+ Ref<EditorInspectorPlugin3DTexture> plugin;
+ plugin.instance();
+ add_inspector_plugin(plugin);
+}
diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h
new file mode 100644
index 0000000000..4fbf47ecfe
--- /dev/null
+++ b/editor/plugins/texture_3d_editor_plugin.h
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* texture_3d_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEXTURE_3D_EDITOR_PLUGIN_H
+#define TEXTURE_3D_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/resources/shader.h"
+#include "scene/resources/texture.h"
+
+class Texture3DEditor : public Control {
+ GDCLASS(Texture3DEditor, Control);
+
+ SpinBox *layer;
+ Label *info;
+ Ref<Texture3D> texture;
+
+ Ref<Shader> shader;
+ Ref<ShaderMaterial> material;
+
+ Control *texture_rect;
+
+ void _make_shaders();
+
+ void _update_material();
+ bool setting;
+ void _layer_changed(double) {
+ if (!setting) {
+ _update_material();
+ }
+ }
+
+ void _texture_rect_update_area();
+ void _texture_rect_draw();
+
+protected:
+ void _notification(int p_what);
+ void _gui_input(Ref<InputEvent> p_event);
+ void _changed_callback(Object *p_changed, const char *p_prop) override;
+ static void _bind_methods();
+
+public:
+ void edit(Ref<Texture3D> p_texture);
+ Texture3DEditor();
+ ~Texture3DEditor();
+};
+
+class EditorInspectorPlugin3DTexture : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPlugin3DTexture, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object) override;
+ virtual void parse_begin(Object *p_object) override;
+};
+
+class Texture3DEditorPlugin : public EditorPlugin {
+ GDCLASS(Texture3DEditorPlugin, EditorPlugin);
+
+public:
+ virtual String get_name() const override { return "Texture3D"; }
+
+ Texture3DEditorPlugin(EditorNode *p_node);
+};
+
+#endif // TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 762f42abeb..6e722607f7 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -875,7 +875,7 @@ void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_pro
if (!is_visible()) {
return;
}
- if (p_prop == StringName("atlas") || p_prop == StringName("texture")) {
+ if (p_prop == StringName("atlas") || p_prop == StringName("texture") || p_prop == StringName("region")) {
_edit_region();
}
}
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 76dd6e38e0..932ded6938 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -206,8 +206,8 @@ void ThemeEditor::_save_template_cbk(String fname) {
file->store_line("; [value] examples:");
file->store_line("; ");
file->store_line("; Type.item = 6 ; numeric constant. ");
- file->store_line("; Type.item = #FF00FF ; HTML color ");
- file->store_line("; Type.item = #55FF00FF ; HTML color with alpha 55.");
+ file->store_line("; Type.item = #FF00FF ; HTML color (magenta).");
+ file->store_line("; Type.item = #FF00FF55 ; HTML color (magenta with alpha 0x55).");
file->store_line("; Type.item = icon(image.png) ; icon in a png file (relative to theme file).");
file->store_line("; Type.item = font(font.xres) ; font in a resource (relative to theme file).");
file->store_line("; Type.item = sbox(stylebox.xres) ; stylebox in a resource (relative to theme file).");
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index e71485e9fc..8cd8aaf277 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -802,7 +802,6 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
r.size = node->get_tileset()->autotile_get_size(p_cell);
r.position += (r.size + Vector2(spacing, spacing)) * offset;
}
- Size2 sc = p_xform.get_scale();
Size2 cell_size = node->get_cell_size();
bool centered_texture = node->is_centered_textures_enabled();
bool compatibility_mode_enabled = node->is_compatibility_mode_enabled();
@@ -838,12 +837,12 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
}
if (p_flip_h) {
- sc.x *= -1.0;
+ rect.size.x *= -1.0;
tile_ofs.x *= -1.0;
}
if (p_flip_v) {
- sc.y *= -1.0;
+ rect.size.y *= -1.0;
tile_ofs.y *= -1.0;
}
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 274c64263f..684d8f0f10 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -3109,6 +3109,7 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
anchor += tileset->tile_get_region(get_current_tile()).position;
anchor += WORKSPACE_MARGIN;
Rect2 region(anchor, tile_size);
+ Rect2 tile_region(tileset->tile_get_region(get_current_tile()).position + WORKSPACE_MARGIN, tileset->tile_get_region(get_current_tile()).size);
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
region.position = tileset->tile_get_region(get_current_tile()).position + WORKSPACE_MARGIN;
region.size = tileset->tile_get_region(get_current_tile()).size;
@@ -3118,6 +3119,7 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
p.x = Math::snap_scalar_separation(snap_offset.x, snap_step.x, p.x, snap_separation.x);
p.y = Math::snap_scalar_separation(snap_offset.y, snap_step.y, p.y, snap_separation.y);
}
+
if (tools[SHAPE_KEEP_INSIDE_TILE]->is_pressed()) {
if (p.x < region.position.x) {
p.x = region.position.x;
@@ -3132,6 +3134,20 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
p.y = region.position.y + region.size.y;
}
}
+
+ if (p.x < tile_region.position.x) {
+ p.x = tile_region.position.x;
+ }
+ if (p.y < tile_region.position.y) {
+ p.y = tile_region.position.y;
+ }
+ if (p.x > (tile_region.position.x + tile_region.size.x)) {
+ p.x = (tile_region.position.x + tile_region.size.x);
+ }
+ if (p.y > (tile_region.position.y + tile_region.size.y)) {
+ p.y = (tile_region.position.y + tile_region.size.y);
+ }
+
return p;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 53bd1150ec..c14d07789f 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -60,6 +60,572 @@ void VisualShaderNodePlugin::_bind_methods() {
///////////////////
+static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
+ Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty));
+ style->set_default_margin(MARGIN_LEFT, p_margin_left * EDSCALE);
+ style->set_default_margin(MARGIN_RIGHT, p_margin_right * EDSCALE);
+ style->set_default_margin(MARGIN_BOTTOM, p_margin_bottom * EDSCALE);
+ style->set_default_margin(MARGIN_TOP, p_margin_top * EDSCALE);
+ return style;
+}
+
+///////////////////
+
+VisualShaderGraphPlugin::VisualShaderGraphPlugin() {
+}
+
+void VisualShaderGraphPlugin::_bind_methods() {
+ ClassDB::bind_method("add_node", &VisualShaderGraphPlugin::add_node);
+ ClassDB::bind_method("remove_node", &VisualShaderGraphPlugin::remove_node);
+ ClassDB::bind_method("connect_nodes", &VisualShaderGraphPlugin::connect_nodes);
+ ClassDB::bind_method("disconnect_nodes", &VisualShaderGraphPlugin::disconnect_nodes);
+ ClassDB::bind_method("set_node_position", &VisualShaderGraphPlugin::set_node_position);
+ ClassDB::bind_method("set_node_size", &VisualShaderGraphPlugin::set_node_size);
+ ClassDB::bind_method("show_port_preview", &VisualShaderGraphPlugin::show_port_preview);
+ ClassDB::bind_method("update_node", &VisualShaderGraphPlugin::update_node);
+ ClassDB::bind_method("update_node_deferred", &VisualShaderGraphPlugin::update_node_deferred);
+ ClassDB::bind_method("set_input_port_default_value", &VisualShaderGraphPlugin::set_input_port_default_value);
+ ClassDB::bind_method("set_uniform_name", &VisualShaderGraphPlugin::set_uniform_name);
+}
+
+void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) {
+ visual_shader = Ref<VisualShader>(p_shader);
+}
+
+void VisualShaderGraphPlugin::set_connections(List<VisualShader::Connection> &p_connections) {
+ connections = p_connections;
+}
+
+void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id) {
+ if (visual_shader->get_shader_type() == p_type && links.has(p_node_id)) {
+ for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) {
+ E->value().preview_button->set_pressed(false);
+ }
+
+ if (links[p_node_id].preview_visible && !is_dirty() && links[p_node_id].preview_box != nullptr) {
+ links[p_node_id].graph_node->remove_child(links[p_node_id].preview_box);
+ memdelete(links[p_node_id].preview_box);
+ links[p_node_id].graph_node->set_size(Vector2(-1, -1));
+ links[p_node_id].preview_visible = false;
+ }
+
+ if (p_port_id != -1) {
+ if (is_dirty()) {
+ links[p_node_id].preview_pos = links[p_node_id].graph_node->get_child_count();
+ }
+
+ VBoxContainer *vbox = memnew(VBoxContainer);
+ links[p_node_id].graph_node->add_child(vbox);
+ if (links[p_node_id].preview_pos != -1) {
+ links[p_node_id].graph_node->move_child(vbox, links[p_node_id].preview_pos);
+ }
+
+ Control *offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
+ vbox->add_child(offset);
+
+ VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
+ port_preview->setup(visual_shader, visual_shader->get_shader_type(), p_node_id, p_port_id);
+ port_preview->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
+ vbox->add_child(port_preview);
+ links[p_node_id].preview_visible = true;
+ links[p_node_id].preview_box = vbox;
+ links[p_node_id].output_ports[p_port_id].preview_button->set_pressed(true);
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::update_node_deferred(VisualShader::Type p_type, int p_node_id) {
+ call_deferred("update_node", p_type, p_node_id);
+}
+
+void VisualShaderGraphPlugin::update_node(VisualShader::Type p_type, int p_node_id) {
+ if (p_type != visual_shader->get_shader_type() || !links.has(p_node_id)) {
+ return;
+ }
+ remove_node(p_type, p_node_id);
+ add_node(p_type, p_node_id);
+}
+
+void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value) {
+ if (p_type != visual_shader->get_shader_type() || !links.has(p_node_id)) {
+ return;
+ }
+
+ Button *button = links[p_node_id].input_ports[p_port_id].default_input_button;
+
+ switch (p_value.get_type()) {
+ case Variant::COLOR: {
+ button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
+ if (!button->is_connected("draw", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_draw_color_over_button))) {
+ button->connect("draw", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_draw_color_over_button), varray(button, p_value));
+ }
+ } break;
+ case Variant::BOOL: {
+ button->set_text(((bool)p_value) ? "true" : "false");
+ } break;
+ case Variant::INT:
+ case Variant::FLOAT: {
+ button->set_text(String::num(p_value, 4));
+ } break;
+ case Variant::VECTOR3: {
+ Vector3 v = p_value;
+ button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3));
+ } break;
+ default: {
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name) {
+ if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].uniform_name != nullptr) {
+ links[p_node_id].uniform_name->set_text(p_name);
+ }
+}
+
+void VisualShaderGraphPlugin::register_default_input_button(int p_node_id, int p_port_id, Button *p_button) {
+ links[p_node_id].input_ports.insert(p_port_id, { p_button });
+}
+
+void VisualShaderGraphPlugin::update_uniform_refs() {
+ for (Map<int, Link>::Element *E = links.front(); E; E = E->next()) {
+ VisualShaderNodeUniformRef *ref = Object::cast_to<VisualShaderNodeUniformRef>(E->get().visual_node);
+ if (ref) {
+ remove_node(E->get().type, E->key());
+ add_node(E->get().type, E->key());
+ }
+ }
+}
+
+VisualShader::Type VisualShaderGraphPlugin::get_shader_type() const {
+ return visual_shader->get_shader_type();
+}
+
+void VisualShaderGraphPlugin::set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position) {
+ if (visual_shader->get_shader_type() == p_type && links.has(p_id)) {
+ links[p_id].graph_node->set_offset(p_position);
+ }
+}
+
+void VisualShaderGraphPlugin::set_node_size(VisualShader::Type p_type, int p_id, const Vector2 &p_size) {
+ if (visual_shader->get_shader_type() == p_type && links.has(p_id)) {
+ links[p_id].graph_node->set_size(p_size);
+ }
+}
+
+bool VisualShaderGraphPlugin::is_preview_visible(int p_id) const {
+ return links[p_id].preview_visible;
+}
+
+void VisualShaderGraphPlugin::clear_links() {
+ links.clear();
+}
+
+bool VisualShaderGraphPlugin::is_dirty() const {
+ return dirty;
+}
+
+void VisualShaderGraphPlugin::make_dirty(bool p_enabled) {
+ dirty = p_enabled;
+}
+
+void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) {
+ links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr });
+}
+
+void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) {
+ links[p_node_id].output_ports.insert(p_port, { p_button });
+}
+
+void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_uniform_name) {
+ links[p_node_id].uniform_name = p_uniform_name;
+}
+
+void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
+ if (p_type != visual_shader->get_shader_type()) {
+ return;
+ }
+
+ Control *offset;
+
+ static Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1);
+
+ static const Color type_color[6] = {
+ Color(0.38, 0.85, 0.96), // scalar (float)
+ Color(0.49, 0.78, 0.94), // scalar (int)
+ Color(0.84, 0.49, 0.93), // vector
+ Color(0.55, 0.65, 0.94), // boolean
+ Color(0.96, 0.66, 0.43), // transform
+ Color(1.0, 1.0, 0.0), // sampler
+ };
+
+ Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id);
+
+ Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr());
+ bool is_group = !group_node.is_null();
+ Size2 size = Size2(0, 0);
+
+ Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr());
+ bool is_expression = !expression_node.is_null();
+ String expression = "";
+
+ GraphNode *node = memnew(GraphNode);
+ register_link(p_type, p_id, vsnode.ptr(), node);
+
+ if (is_group) {
+ size = group_node->get_size();
+
+ node->set_resizable(true);
+ node->connect("resize_request", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_node_resized), varray((int)p_type, p_id));
+ }
+ if (is_expression) {
+ expression = expression_node->get_expression();
+ }
+
+ node->set_offset(visual_shader->get_node_position(p_type, p_id));
+ node->set_title(vsnode->get_caption());
+ node->set_name(itos(p_id));
+
+ if (p_id >= 2) {
+ node->set_show_close_button(true);
+ node->connect("close_request", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_delete_request), varray(p_id), CONNECT_DEFERRED);
+ }
+
+ node->connect("dragged", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_node_dragged), varray(p_id));
+
+ Control *custom_editor = nullptr;
+ int port_offset = 0;
+
+ if (is_group) {
+ port_offset += 2;
+ }
+
+ Ref<VisualShaderNodeUniform> uniform = vsnode;
+ if (uniform.is_valid()) {
+ VisualShaderEditor::get_singleton()->graph->add_child(node);
+ VisualShaderEditor::get_singleton()->_update_created_node(node);
+
+ LineEdit *uniform_name = memnew(LineEdit);
+ register_uniform_name(p_id, uniform_name);
+ uniform_name->set_text(uniform->get_uniform_name());
+ node->add_child(uniform_name);
+ uniform_name->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_changed), varray(p_id));
+ uniform_name->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_uniform_line_edit_focus_out), varray(uniform_name, p_id));
+
+ if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") {
+ //shortcut
+ VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
+ node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]);
+ if (!vsnode->is_use_prop_slots()) {
+ return;
+ }
+ }
+ port_offset++;
+ }
+
+ for (int i = 0; i < VisualShaderEditor::get_singleton()->plugins.size(); i++) {
+ vsnode->set_meta("id", p_id);
+ vsnode->set_meta("shader_type", (int)p_type);
+ custom_editor = VisualShaderEditor::get_singleton()->plugins.write[i]->create_editor(visual_shader, vsnode);
+ vsnode->remove_meta("id");
+ vsnode->remove_meta("shader_type");
+ if (custom_editor) {
+ if (vsnode->is_show_prop_names()) {
+ custom_editor->call_deferred("_show_prop_names", true);
+ }
+ break;
+ }
+ }
+
+ if (custom_editor && !vsnode->is_use_prop_slots() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
+ //will be embedded in first port
+ } else if (custom_editor) {
+ port_offset++;
+ node->add_child(custom_editor);
+ if (vsnode->is_use_prop_slots()) {
+ return;
+ }
+ custom_editor = nullptr;
+ }
+
+ if (is_group) {
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
+ node->add_child(offset);
+
+ if (group_node->is_editable()) {
+ HBoxContainer *hb2 = memnew(HBoxContainer);
+
+ Button *add_input_btn = memnew(Button);
+ add_input_btn->set_text(TTR("Add Input"));
+ add_input_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_input_port), varray(p_id, 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);
+
+ hb2->add_spacer();
+
+ Button *add_output_btn = memnew(Button);
+ add_output_btn->set_text(TTR("Add Output"));
+ add_output_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_output_port), varray(p_id, 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++) {
+ if (vsnode->is_port_separator(i)) {
+ node->add_child(memnew(HSeparator));
+ port_offset++;
+ }
+
+ bool valid_left = i < vsnode->get_input_port_count();
+ VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ bool port_left_used = false;
+ String name_left;
+ if (valid_left) {
+ name_left = vsnode->get_input_port_name(i);
+ port_left = vsnode->get_input_port_type(i);
+ for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
+ if (E->get().to_node == p_id && E->get().to_port == i) {
+ port_left_used = true;
+ }
+ }
+ }
+
+ bool valid_right = i < vsnode->get_output_port_count();
+ VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR;
+ String name_right;
+ if (valid_right) {
+ name_right = vsnode->get_output_port_name(i);
+ port_right = vsnode->get_output_port_type(i);
+ }
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_theme_constant_override("separation", 7 * EDSCALE);
+
+ Variant default_value;
+
+ if (valid_left && !port_left_used) {
+ default_value = vsnode->get_input_port_default_value(i);
+ }
+
+ Button *button = memnew(Button);
+ hb->add_child(button);
+ register_default_input_button(p_id, i, button);
+ button->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_edit_port_default_input), varray(button, p_id, i));
+ if (default_value.get_type() != Variant::NIL) { // only a label
+ set_input_port_default_value(p_type, p_id, i, default_value);
+ } else {
+ button->hide();
+ }
+
+ if (i == 0 && custom_editor) {
+ hb->add_child(custom_editor);
+ custom_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ } else {
+ if (valid_left) {
+ if (is_group) {
+ OptionButton *type_box = memnew(OptionButton);
+ hb->add_child(type_box);
+ type_box->add_item(TTR("Float"));
+ type_box->add_item(TTR("Int"));
+ type_box->add_item(TTR("Vector"));
+ type_box->add_item(TTR("Boolean"));
+ type_box->add_item(TTR("Transform"));
+ type_box->add_item(TTR("Sampler"));
+ type_box->select(group_node->get_input_port_type(i));
+ type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
+ type_box->connect("item_selected", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_type), varray(p_id, i), CONNECT_DEFERRED);
+
+ LineEdit *name_box = memnew(LineEdit);
+ hb->add_child(name_box);
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ name_box->set_text(name_left);
+ name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i));
+ name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false));
+
+ Button *remove_btn = memnew(Button);
+ remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
+ remove_btn->set_tooltip(TTR("Remove") + " " + name_left);
+ remove_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_remove_input_port), varray(p_id, i), CONNECT_DEFERRED);
+ hb->add_child(remove_btn);
+ } else {
+ Label *label = memnew(Label);
+ label->set_text(name_left);
+ label->add_theme_style_override("normal", label_style); //more compact
+ hb->add_child(label);
+
+ if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) {
+ Label *hint_label = memnew(Label);
+ hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]");
+ hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_color_readonly", "TextEdit"));
+ hint_label->add_theme_style_override("normal", label_style);
+ hb->add_child(hint_label);
+ }
+ }
+ }
+
+ if (!is_group) {
+ hb->add_spacer();
+ }
+
+ if (valid_right) {
+ if (is_group) {
+ Button *remove_btn = memnew(Button);
+ remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
+ remove_btn->set_tooltip(TTR("Remove") + " " + name_left);
+ remove_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_remove_output_port), varray(p_id, i), CONNECT_DEFERRED);
+ hb->add_child(remove_btn);
+
+ LineEdit *name_box = memnew(LineEdit);
+ hb->add_child(name_box);
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ name_box->set_text(name_right);
+ name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i));
+ name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true));
+
+ OptionButton *type_box = memnew(OptionButton);
+ hb->add_child(type_box);
+ type_box->add_item(TTR("Float"));
+ type_box->add_item(TTR("Int"));
+ type_box->add_item(TTR("Vector"));
+ type_box->add_item(TTR("Boolean"));
+ type_box->add_item(TTR("Transform"));
+ type_box->select(group_node->get_output_port_type(i));
+ type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
+ type_box->connect("item_selected", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_type), varray(p_id, i), CONNECT_DEFERRED);
+ } else {
+ Label *label = memnew(Label);
+ label->set_text(name_right);
+ label->add_theme_style_override("normal", label_style); //more compact
+ hb->add_child(label);
+ }
+ }
+ }
+
+ if (valid_right && visual_shader->get_shader_type() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) {
+ TextureButton *preview = memnew(TextureButton);
+ preview->set_toggle_mode(true);
+ preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
+ preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
+ preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
+
+ register_output_port(p_id, i, preview);
+
+ preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, i), CONNECT_DEFERRED);
+ hb->add_child(preview);
+ }
+
+ if (is_group) {
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
+ node->add_child(offset);
+ port_offset++;
+ }
+
+ node->add_child(hb);
+
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
+ }
+
+ if (vsnode->get_output_port_for_preview() >= 0) {
+ show_port_preview(p_type, p_id, vsnode->get_output_port_for_preview());
+ }
+
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
+ node->add_child(offset);
+
+ String error = vsnode->get_warning(visual_shader->get_mode(), p_type);
+ if (error != String()) {
+ Label *error_label = memnew(Label);
+ error_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("error_color", "Editor"));
+ error_label->set_text(error);
+ node->add_child(error_label);
+ }
+
+ if (is_expression) {
+ CodeEdit *expression_box = memnew(CodeEdit);
+ Ref<CodeHighlighter> expression_syntax_highlighter;
+ expression_syntax_highlighter.instance();
+ 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");
+ Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
+ Color number_color = EDITOR_GET("text_editor/highlighting/number_color");
+ Color members_color = EDITOR_GET("text_editor/highlighting/member_variable_color");
+
+ expression_box->set_syntax_highlighter(expression_syntax_highlighter);
+ expression_box->add_theme_color_override("background_color", background_color);
+
+ for (List<String>::Element *E = VisualShaderEditor::get_singleton()->keyword_list.front(); E; E = E->next()) {
+ expression_syntax_highlighter->add_keyword_color(E->get(), keyword_color);
+ }
+
+ expression_box->add_theme_font_override("font", VisualShaderEditor::get_singleton()->get_theme_font("expression", "EditorFonts"));
+ expression_box->add_theme_color_override("font_color", text_color);
+ expression_syntax_highlighter->set_number_color(number_color);
+ expression_syntax_highlighter->set_symbol_color(symbol_color);
+ expression_syntax_highlighter->set_function_color(function_color);
+ expression_syntax_highlighter->set_member_variable_color(members_color);
+ expression_syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
+ expression_syntax_highlighter->add_color_region("//", "", comment_color, true);
+
+ expression_box->set_text(expression);
+ expression_box->set_context_menu_enabled(false);
+ expression_box->set_draw_line_numbers(true);
+
+ expression_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_expression_focus_out), varray(expression_box, p_id));
+ }
+
+ if (!uniform.is_valid()) {
+ VisualShaderEditor::get_singleton()->graph->add_child(node);
+ VisualShaderEditor::get_singleton()->_update_created_node(node);
+ if (is_group) {
+ VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size);
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::remove_node(VisualShader::Type p_type, int p_id) {
+ if (visual_shader->get_shader_type() == p_type && links.has(p_id)) {
+ links[p_id].graph_node->get_parent()->remove_child(links[p_id].graph_node);
+ memdelete(links[p_id].graph_node);
+ links.erase(p_id);
+ }
+}
+
+void VisualShaderGraphPlugin::connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
+ if (visual_shader->get_shader_type() == p_type) {
+ VisualShaderEditor::get_singleton()->graph->connect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr) {
+ links[p_to_node].input_ports[p_to_port].default_input_button->hide();
+ }
+ }
+}
+
+void VisualShaderGraphPlugin::disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
+ if (visual_shader->get_shader_type() == p_type) {
+ VisualShaderEditor::get_singleton()->graph->disconnect_node(itos(p_from_node), p_from_port, itos(p_to_node), p_to_port);
+ if (links[p_to_node].input_ports.has(p_to_port) && links[p_to_node].input_ports[p_to_port].default_input_button != nullptr && links[p_to_node].visual_node->get_input_port_default_value(p_to_port).get_type() != Variant::NIL) {
+ links[p_to_node].input_ports[p_to_port].default_input_button->show();
+ set_input_port_default_value(p_type, p_to_node, p_to_port, links[p_to_node].visual_node->get_input_port_default_value(p_to_port));
+ }
+ }
+}
+
+VisualShaderGraphPlugin::~VisualShaderGraphPlugin() {
+}
+
+/////////////////
+
void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
bool changed = false;
if (p_visual_shader) {
@@ -71,6 +637,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
}
visual_shader = Ref<VisualShader>(p_visual_shader);
+ graph_plugin->register_shader(visual_shader.ptr());
if (!visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) {
visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview));
}
@@ -81,6 +648,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
#endif
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
+ _set_mode(visual_shader->get_mode());
} else {
if (visual_shader.is_valid()) {
if (visual_shader->is_connected("changed", callable_mp(this, &VisualShaderEditor::_update_preview))) {
@@ -97,8 +665,8 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
_clear_buffer();
_update_options_menu();
_update_preview();
+ _update_graph();
}
- _update_graph();
}
}
@@ -168,34 +736,18 @@ bool VisualShaderEditor::_is_available(int p_mode) {
if (p_mode != -1) {
switch (current_mode) {
- case VisualShader::TYPE_VERTEX:
+ case 0: // Vertex or Emit
current_mode = 1;
break;
- case VisualShader::TYPE_FRAGMENT:
+ case 1: // Fragment or Process
current_mode = 2;
break;
- case VisualShader::TYPE_LIGHT:
+ case 2: // Light or End
current_mode = 4;
break;
default:
break;
}
-
- int temp_mode = 0;
-
- if (p_mode & VisualShader::TYPE_FRAGMENT) {
- temp_mode |= 2;
- }
-
- if (p_mode & VisualShader::TYPE_LIGHT) {
- temp_mode |= 4;
- }
-
- if (temp_mode == 0) {
- temp_mode |= 1;
- }
-
- p_mode = temp_mode;
}
return (p_mode == -1 || (p_mode & current_mode) != 0);
@@ -404,6 +956,21 @@ void VisualShaderEditor::_update_options_menu() {
}
}
+void VisualShaderEditor::_set_mode(int p_which) {
+ if (p_which == VisualShader::MODE_PARTICLES) {
+ edit_type_standart->set_visible(false);
+ edit_type_particles->set_visible(true);
+ edit_type = edit_type_particles;
+ particles_mode = true;
+ } else {
+ edit_type_particles->set_visible(false);
+ edit_type_standart->set_visible(true);
+ edit_type = edit_type_standart;
+ particles_mode = false;
+ }
+ visual_shader->set_shader_type(get_current_shader_type());
+}
+
Size2 VisualShaderEditor::get_minimum_size() const {
return Size2(10, 200);
}
@@ -418,15 +985,6 @@ void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) {
button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color);
}
-static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
- Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty));
- style->set_default_margin(MARGIN_LEFT, p_margin_left * EDSCALE);
- style->set_default_margin(MARGIN_RIGHT, p_margin_right * EDSCALE);
- style->set_default_margin(MARGIN_BOTTOM, p_margin_bottom * EDSCALE);
- style->set_default_margin(MARGIN_TOP, p_margin_top * EDSCALE);
- return style;
-}
-
void VisualShaderEditor::_update_created_node(GraphNode *node) {
if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
Ref<StyleBoxFlat> sb = node->get_theme_stylebox("frame", "GraphNode");
@@ -450,49 +1008,9 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) {
}
}
-void VisualShaderEditor::_update_graph() {
- if (updating) {
- return;
- }
-
- if (visual_shader.is_null()) {
- return;
- }
-
- graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE);
-
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
- graph->clear_connections();
- //erase all nodes
- for (int i = 0; i < graph->get_child_count(); i++) {
- if (Object::cast_to<GraphNode>(graph->get_child(i))) {
- Node *node = graph->get_child(i);
- graph->remove_child(node);
- memdelete(node);
- i--;
- }
- }
-
- static const Color type_color[6] = {
- Color(0.38, 0.85, 0.96), // scalar (float)
- Color(0.49, 0.78, 0.94), // scalar (int)
- Color(0.84, 0.49, 0.93), // vector
- Color(0.55, 0.65, 0.94), // boolean
- Color(0.96, 0.66, 0.43), // transform
- Color(1.0, 1.0, 0.0), // sampler
- };
-
- List<VisualShader::Connection> connections;
- visual_shader->get_node_connections(type, &connections);
-
- Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1);
-
- Vector<int> nodes = visual_shader->get_node_list(type);
-
+void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
VisualShaderNodeUniformRef::clear_uniforms();
- // scan for all uniforms
-
for (int t = 0; t < VisualShader::TYPE_MAX; t++) {
Vector<int> tnodes = visual_shader->get_node_list((VisualShader::Type)t);
for (int i = 0; i < tnodes.size(); i++) {
@@ -527,388 +1045,73 @@ void VisualShaderEditor::_update_graph() {
}
}
}
+ if (p_update_refs) {
+ graph_plugin->update_uniform_refs();
+ }
+}
- Control *offset;
-
- for (int n_i = 0; n_i < nodes.size(); n_i++) {
- Vector2 position = visual_shader->get_node_position(type, nodes[n_i]);
- Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]);
-
- Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr());
- bool is_group = !group_node.is_null();
- Size2 size = Size2(0, 0);
-
- Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr());
- bool is_expression = !expression_node.is_null();
- String expression = "";
-
- GraphNode *node = memnew(GraphNode);
-
- if (is_group) {
- size = group_node->get_size();
-
- node->set_resizable(true);
- node->connect("resize_request", callable_mp(this, &VisualShaderEditor::_node_resized), varray((int)type, nodes[n_i]));
- }
- if (is_expression) {
- expression = expression_node->get_expression();
- }
-
- node->set_offset(position);
-
- node->set_title(vsnode->get_caption());
- node->set_name(itos(nodes[n_i]));
-
- if (nodes[n_i] >= 2) {
- node->set_show_close_button(true);
- node->connect("close_request", callable_mp(this, &VisualShaderEditor::_delete_request), varray(nodes[n_i]), CONNECT_DEFERRED);
- }
-
- node->connect("dragged", callable_mp(this, &VisualShaderEditor::_node_dragged), varray(nodes[n_i]));
-
- Control *custom_editor = nullptr;
- int port_offset = 0;
-
- if (is_group) {
- port_offset += 2;
- }
-
- Ref<VisualShaderNodeUniform> uniform = vsnode;
- Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode;
- Ref<VisualShaderNodeIntUniform> int_uniform = vsnode;
- Ref<VisualShaderNodeVec3Uniform> vec3_uniform = vsnode;
- Ref<VisualShaderNodeColorUniform> color_uniform = vsnode;
- Ref<VisualShaderNodeBooleanUniform> bool_uniform = vsnode;
- Ref<VisualShaderNodeTransformUniform> transform_uniform = vsnode;
- if (uniform.is_valid()) {
- graph->add_child(node);
- _update_created_node(node);
-
- LineEdit *uniform_name = memnew(LineEdit);
- uniform_name->set_text(uniform->get_uniform_name());
- node->add_child(uniform_name);
- uniform_name->connect("text_entered", callable_mp(this, &VisualShaderEditor::_line_edit_changed), varray(uniform_name, nodes[n_i]));
- uniform_name->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_line_edit_focus_out), varray(uniform_name, nodes[n_i]));
-
- String error = vsnode->get_warning(visual_shader->get_mode(), type);
- if (error != String()) {
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
- node->add_child(offset);
- Label *error_label = memnew(Label);
- error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
- error_label->set_text(error);
- node->add_child(error_label);
- }
-
- if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") {
- //shortcut
- VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
- node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]);
- if (!float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !color_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid()) {
- continue;
- }
- }
- port_offset++;
- }
-
- for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins.write[i]->create_editor(visual_shader, vsnode);
- if (custom_editor) {
- break;
- }
- }
-
- if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
- //will be embedded in first port
- } else if (custom_editor) {
- port_offset++;
- node->add_child(custom_editor);
- if (color_uniform.is_valid()) {
- custom_editor->call_deferred("_show_prop_names", true);
- }
- if (float_uniform.is_valid() || int_uniform.is_valid() || vec3_uniform.is_valid() || bool_uniform.is_valid() || transform_uniform.is_valid()) {
- custom_editor->call_deferred("_show_prop_names", true);
- continue;
- }
- custom_editor = nullptr;
- }
-
- if (is_group) {
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
- node->add_child(offset);
-
- if (group_node->is_editable()) {
- HBoxContainer *hb2 = memnew(HBoxContainer);
-
- Button *add_input_btn = memnew(Button);
- add_input_btn->set_text(TTR("Add Input"));
- add_input_btn->connect("pressed", callable_mp(this, &VisualShaderEditor::_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);
-
- hb2->add_spacer();
-
- Button *add_output_btn = memnew(Button);
- add_output_btn->set_text(TTR("Add Output"));
- add_output_btn->connect("pressed", callable_mp(this, &VisualShaderEditor::_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++) {
- if (vsnode->is_port_separator(i)) {
- node->add_child(memnew(HSeparator));
- port_offset++;
- }
-
- bool valid_left = i < vsnode->get_input_port_count();
- VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- bool port_left_used = false;
- String name_left;
- if (valid_left) {
- name_left = vsnode->get_input_port_name(i);
- port_left = vsnode->get_input_port_type(i);
- for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
- if (E->get().to_node == nodes[n_i] && E->get().to_port == i) {
- port_left_used = true;
- }
- }
- }
-
- bool valid_right = i < vsnode->get_output_port_count();
- VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR;
- String name_right;
- if (valid_right) {
- name_right = vsnode->get_output_port_name(i);
- port_right = vsnode->get_output_port_type(i);
- }
-
- HBoxContainer *hb = memnew(HBoxContainer);
- hb->add_theme_constant_override("separation", 7 * EDSCALE);
-
- Variant default_value;
-
- if (valid_left && !port_left_used) {
- default_value = vsnode->get_input_port_default_value(i);
- }
-
- if (default_value.get_type() != Variant::NIL) { // only a label
- Button *button = memnew(Button);
- hb->add_child(button);
- button->connect("pressed", callable_mp(this, &VisualShaderEditor::_edit_port_default_input), varray(button, nodes[n_i], i));
-
- switch (default_value.get_type()) {
- case Variant::COLOR: {
- button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
- button->connect("draw", callable_mp(this, &VisualShaderEditor::_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::FLOAT: {
- button->set_text(String::num(default_value, 4));
- } break;
- case Variant::VECTOR3: {
- Vector3 v = default_value;
- button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3));
- } break;
- default: {
- }
- }
- }
-
- if (i == 0 && custom_editor) {
- hb->add_child(custom_editor);
- custom_editor->set_h_size_flags(SIZE_EXPAND_FILL);
- } else {
- if (valid_left) {
- if (is_group) {
- OptionButton *type_box = memnew(OptionButton);
- hb->add_child(type_box);
- type_box->add_item(TTR("Float"));
- type_box->add_item(TTR("Int"));
- type_box->add_item(TTR("Vector"));
- type_box->add_item(TTR("Boolean"));
- type_box->add_item(TTR("Transform"));
- type_box->add_item(TTR("Sampler"));
- type_box->select(group_node->get_input_port_type(i));
- type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- type_box->connect("item_selected", callable_mp(this, &VisualShaderEditor::_change_input_port_type), varray(nodes[n_i], i), CONNECT_DEFERRED);
-
- LineEdit *name_box = memnew(LineEdit);
- hb->add_child(name_box);
- 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->connect("text_entered", callable_mp(this, &VisualShaderEditor::_change_input_port_name), varray(name_box, nodes[n_i], i));
- name_box->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_port_name_focus_out), varray(name_box, nodes[n_i], i, false));
-
- Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
- remove_btn->set_tooltip(TTR("Remove") + " " + name_left);
- remove_btn->connect("pressed", callable_mp(this, &VisualShaderEditor::_remove_input_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
- hb->add_child(remove_btn);
- } else {
- Label *label = memnew(Label);
- label->set_text(name_left);
- label->add_theme_style_override("normal", label_style); //more compact
- hb->add_child(label);
-
- if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) {
- Label *hint_label = memnew(Label);
- hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]");
- hint_label->add_theme_color_override("font_color", get_theme_color("font_color_readonly", "TextEdit"));
- hint_label->add_theme_style_override("normal", label_style);
- hb->add_child(hint_label);
- }
- }
- }
-
- if (!is_group) {
- hb->add_spacer();
- }
+void VisualShaderEditor::_update_uniform_refs(Set<String> &p_deleted_names) {
+ for (int i = 0; i < VisualShader::TYPE_MAX; i++) {
+ VisualShader::Type type = VisualShader::Type(i);
- if (valid_right) {
- if (is_group) {
- Button *remove_btn = memnew(Button);
- remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
- remove_btn->set_tooltip(TTR("Remove") + " " + name_left);
- remove_btn->connect("pressed", callable_mp(this, &VisualShaderEditor::_remove_output_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
- hb->add_child(remove_btn);
-
- LineEdit *name_box = memnew(LineEdit);
- hb->add_child(name_box);
- 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->connect("text_entered", callable_mp(this, &VisualShaderEditor::_change_output_port_name), varray(name_box, nodes[n_i], i));
- name_box->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_port_name_focus_out), varray(name_box, nodes[n_i], i, true));
-
- OptionButton *type_box = memnew(OptionButton);
- hb->add_child(type_box);
- type_box->add_item(TTR("Float"));
- type_box->add_item(TTR("Int"));
- type_box->add_item(TTR("Vector"));
- type_box->add_item(TTR("Boolean"));
- type_box->add_item(TTR("Transform"));
- type_box->select(group_node->get_output_port_type(i));
- type_box->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- type_box->connect("item_selected", callable_mp(this, &VisualShaderEditor::_change_output_port_type), varray(nodes[n_i], i), CONNECT_DEFERRED);
- } else {
- Label *label = memnew(Label);
- label->set_text(name_right);
- label->add_theme_style_override("normal", label_style); //more compact
- hb->add_child(label);
+ Vector<int> nodes = visual_shader->get_node_list(type);
+ for (int j = 0; j < nodes.size(); j++) {
+ if (j > 0) {
+ Ref<VisualShaderNodeUniformRef> ref = visual_shader->get_node(type, nodes[j]);
+ if (ref.is_valid()) {
+ if (p_deleted_names.has(ref->get_uniform_name())) {
+ undo_redo->add_do_method(ref.ptr(), "set_uniform_name", "[None]");
+ undo_redo->add_undo_method(ref.ptr(), "set_uniform_name", ref->get_uniform_name());
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", VisualShader::Type(i), nodes[j]);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", VisualShader::Type(i), nodes[j]);
}
}
}
-
- if (valid_right && edit_type->get_selected() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) {
- TextureButton *preview = memnew(TextureButton);
- preview->set_toggle_mode(true);
- preview->set_normal_texture(get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
- preview->set_pressed_texture(get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
- preview->set_v_size_flags(SIZE_SHRINK_CENTER);
-
- if (vsnode->get_output_port_for_preview() == i) {
- preview->set_pressed(true);
- }
-
- preview->connect("pressed", callable_mp(this, &VisualShaderEditor::_preview_select_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
- hb->add_child(preview);
- }
-
- if (is_group) {
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
- node->add_child(offset);
- port_offset++;
- }
-
- node->add_child(hb);
-
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
}
+ }
+}
- if (vsnode->get_output_port_for_preview() >= 0) {
- int port_type = vsnode->get_output_port_type(vsnode->get_output_port_for_preview());
+void VisualShaderEditor::_update_graph() {
+ if (updating) {
+ return;
+ }
- if (port_type != VisualShaderNode::PORT_TYPE_TRANSFORM && port_type != VisualShaderNode::PORT_TYPE_SAMPLER) {
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
- node->add_child(offset);
+ if (visual_shader.is_null()) {
+ return;
+ }
- VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview);
- port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview());
- port_preview->set_h_size_flags(SIZE_SHRINK_CENTER);
- node->add_child(port_preview);
- }
- }
+ graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE);
- offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
- node->add_child(offset);
+ VisualShader::Type type = get_current_shader_type();
- String error = vsnode->get_warning(visual_shader->get_mode(), type);
- if (error != String()) {
- Label *error_label = memnew(Label);
- error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
- error_label->set_text(error);
- node->add_child(error_label);
+ graph->clear_connections();
+ //erase all nodes
+ for (int i = 0; i < graph->get_child_count(); i++) {
+ if (Object::cast_to<GraphNode>(graph->get_child(i))) {
+ Node *node = graph->get_child(i);
+ graph->remove_child(node);
+ memdelete(node);
+ i--;
}
+ }
- if (is_expression) {
- TextEdit *expression_box = memnew(TextEdit);
- Ref<CodeHighlighter> expression_syntax_highlighter;
- expression_syntax_highlighter.instance();
- 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");
- Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
- Color number_color = EDITOR_GET("text_editor/highlighting/number_color");
- Color members_color = EDITOR_GET("text_editor/highlighting/member_variable_color");
-
- expression_box->set_syntax_highlighter(expression_syntax_highlighter);
- expression_box->add_theme_color_override("background_color", background_color);
-
- for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
- expression_syntax_highlighter->add_keyword_color(E->get(), keyword_color);
- }
+ List<VisualShader::Connection> connections;
+ visual_shader->get_node_connections(type, &connections);
+ graph_plugin->set_connections(connections);
- expression_box->add_theme_font_override("font", get_theme_font("expression", "EditorFonts"));
- expression_box->add_theme_color_override("font_color", text_color);
- expression_syntax_highlighter->set_number_color(number_color);
- expression_syntax_highlighter->set_symbol_color(symbol_color);
- expression_syntax_highlighter->set_function_color(function_color);
- expression_syntax_highlighter->set_member_variable_color(members_color);
- expression_syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
- expression_syntax_highlighter->add_color_region("//", "", comment_color, true);
+ Vector<int> nodes = visual_shader->get_node_list(type);
- expression_box->set_text(expression);
- expression_box->set_context_menu_enabled(false);
- expression_box->set_show_line_numbers(true);
+ _update_uniforms(false);
- expression_box->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_expression_focus_out), varray(expression_box, nodes[n_i]));
- }
+ graph_plugin->clear_links();
+ graph_plugin->make_dirty(true);
- if (!uniform.is_valid()) {
- graph->add_child(node);
- _update_created_node(node);
- if (is_group) {
- call_deferred("_set_node_size", (int)type, nodes[n_i], size);
- }
- }
+ for (int n_i = 0; n_i < nodes.size(); n_i++) {
+ graph_plugin->add_node(type, nodes[n_i]);
}
+ graph_plugin->make_dirty(false);
+
for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
int from = E->get().from_node;
int from_idx = E->get().from_port;
@@ -919,8 +1122,18 @@ void VisualShaderEditor::_update_graph() {
}
}
+VisualShader::Type VisualShaderEditor::get_current_shader_type() const {
+ VisualShader::Type type;
+ if (particles_mode) {
+ type = VisualShader::Type(edit_type->get_selected() + 3);
+ } else {
+ type = VisualShader::Type(edit_type->get_selected());
+ }
+ return type;
+}
+
void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type, const String &p_name) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -929,15 +1142,13 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type
undo_redo->create_action(TTR("Add input port"));
undo_redo->add_do_method(node.ptr(), "add_input_port", p_port, p_port_type, p_name);
undo_redo->add_undo_method(node.ptr(), "remove_input_port", p_port);
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_type, const String &p_name) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -946,15 +1157,13 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ
undo_redo->create_action(TTR("Add output port"));
undo_redo->add_do_method(node.ptr(), "add_output_port", p_port, p_port_type, p_name);
undo_redo->add_undo_method(node.ptr(), "remove_output_port", p_port);
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -963,15 +1172,13 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p
undo_redo->create_action(TTR("Change input port type"));
undo_redo->add_do_method(node.ptr(), "set_input_port_type", p_port, p_type);
undo_redo->add_undo_method(node.ptr(), "set_input_port_type", p_port, node->get_input_port_type(p_port));
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -980,15 +1187,13 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_
undo_redo->create_action(TTR("Change output port type"));
undo_redo->add_do_method(node.ptr(), "set_output_port_type", p_port, p_type);
undo_redo->add_undo_method(node.ptr(), "set_output_port_type", p_port, node->get_output_port_type(p_port));
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
ERR_FAIL_COND(!node.is_valid());
@@ -996,13 +1201,13 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *l
undo_redo->create_action(TTR("Change input port name"));
undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, p_text);
undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id));
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id);
undo_redo->commit_action();
}
void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
ERR_FAIL_COND(!node.is_valid());
@@ -1010,13 +1215,13 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *
undo_redo->create_action(TTR("Change output port name"));
undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, p_text);
undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, node->get_output_port_name(p_port_id));
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id);
undo_redo->commit_action();
}
void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -1036,12 +1241,21 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
if (to_port == p_port) {
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
} else if (to_port > p_port) {
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
+
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port - 1);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port - 1);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port - 1);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port - 1);
}
}
}
@@ -1049,17 +1263,14 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
undo_redo->add_do_method(node.ptr(), "remove_input_port", p_port);
undo_redo->add_undo_method(node.ptr(), "add_input_port", p_port, (int)node->get_input_port_type(p_port), node->get_input_port_name(p_port));
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
-
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -1079,12 +1290,21 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
if (from_port == p_port) {
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
} else if (from_port > p_port) {
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port);
+
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port - 1, to_node, to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port - 1, to_node, to_port);
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port - 1, to_node, to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port - 1, to_node, to_port);
}
}
}
@@ -1092,23 +1312,20 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
undo_redo->add_do_method(node.ptr(), "remove_output_port", p_port);
undo_redo->add_undo_method(node.ptr(), "add_output_port", p_port, (int)node->get_output_port_type(p_port), node->get_output_port_name(p_port));
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
-
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node);
undo_redo->commit_action();
}
-void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) {
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
}
- TextEdit *expression_box = Object::cast_to<TextEdit>(text_edit);
+ CodeEdit *expression_box = Object::cast_to<CodeEdit>(code_edit);
if (node->get_expression() == expression_box->get_text()) {
return;
@@ -1117,20 +1334,11 @@ void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
undo_redo->create_action(TTR("Set expression"));
undo_redo->add_do_method(node.ptr(), "set_expression", expression_box->get_text());
undo_redo->add_undo_method(node.ptr(), "set_expression", node->get_expression());
- undo_redo->add_do_method(this, "_rebuild");
- undo_redo->add_undo_method(this, "_rebuild");
undo_redo->commit_action();
}
-void VisualShaderEditor::_rebuild() {
- if (visual_shader != nullptr) {
- EditorNode::get_singleton()->get_log()->clear();
- visual_shader->rebuild();
- }
-}
-
void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) {
- VisualShader::Type type = VisualShader::Type(p_type);
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -1177,7 +1385,7 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p
}
void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, int p_node) {
- VisualShader::Type type = VisualShader::Type(p_type);
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
@@ -1190,50 +1398,57 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
}
void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
return;
}
-
+ int prev_port = node->get_output_port_for_preview();
if (node->get_output_port_for_preview() == p_port) {
p_port = -1; //toggle it
}
- undo_redo->create_action(TTR("Set Uniform Name"));
+ undo_redo->create_action(p_port == -1 ? TTR("Hide Port Preview") : TTR("Show Port Preview"));
undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", p_port);
- undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", node->get_output_port_for_preview());
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", prev_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "show_port_preview", (int)type, p_node, p_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "show_port_preview", (int)type, p_node, prev_port);
undo_redo->commit_action();
}
-void VisualShaderEditor::_line_edit_changed(const String &p_text, Object *line_edit, int p_node_id) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+void VisualShaderEditor::_uniform_line_edit_changed(const String &p_text, int p_node_id) {
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeUniform> node = visual_shader->get_node(type, p_node_id);
ERR_FAIL_COND(!node.is_valid());
String validated_name = visual_shader->validate_uniform_name(p_text, node);
- updating = true;
+ if (validated_name == node->get_uniform_name()) {
+ return;
+ }
+
undo_redo->create_action(TTR("Set Uniform Name"));
undo_redo->add_do_method(node.ptr(), "set_uniform_name", validated_name);
undo_redo->add_undo_method(node.ptr(), "set_uniform_name", node->get_uniform_name());
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
- undo_redo->commit_action();
- updating = false;
+ undo_redo->add_do_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, validated_name);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "set_uniform_name", type, p_node_id, node->get_uniform_name());
+
+ undo_redo->add_do_method(this, "_update_uniforms", true);
+ undo_redo->add_undo_method(this, "_update_uniforms", true);
+
+ Set<String> changed_names;
+ changed_names.insert(node->get_uniform_name());
+ _update_uniform_refs(changed_names);
- Object::cast_to<LineEdit>(line_edit)->set_text(validated_name);
+ undo_redo->commit_action();
}
-void VisualShaderEditor::_line_edit_focus_out(Object *line_edit, int p_node_id) {
- String text = Object::cast_to<LineEdit>(line_edit)->get_text();
- _line_edit_changed(text, line_edit, p_node_id);
+void VisualShaderEditor::_uniform_line_edit_focus_out(Object *line_edit, int p_node_id) {
+ _uniform_line_edit_changed(Object::cast_to<LineEdit>(line_edit)->get_text(), p_node_id);
}
void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
ERR_FAIL_COND(!node.is_valid());
@@ -1284,7 +1499,7 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id,
}
void VisualShaderEditor::_port_edited() {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Variant value = property_editor->get_variant();
Ref<VisualShaderNode> vsn = visual_shader->get_node(type, editing_node);
@@ -1293,15 +1508,15 @@ void VisualShaderEditor::_port_edited() {
undo_redo->create_action(TTR("Set Input Default Port"));
undo_redo->add_do_method(vsn.ptr(), "set_input_port_default_value", editing_port, value);
undo_redo->add_undo_method(vsn.ptr(), "set_input_port_default_value", editing_port, vsn->get_input_port_default_value(editing_port));
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->add_do_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, value);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "set_input_port_default_value", type, editing_node, editing_port, vsn->get_input_port_default_value(editing_port));
undo_redo->commit_action();
property_editor->hide();
}
void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, int p_port) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNode> vsn = visual_shader->get_node(type, p_node);
@@ -1467,13 +1682,15 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
}
saved_node_pos_dirty = false;
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
int id_to_use = visual_shader->get_valid_node_id(type);
undo_redo->create_action(TTR("Add Node to Visual Shader"));
undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, vsnode, position, id_to_use);
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_to_use);
+ undo_redo->add_do_method(graph_plugin.ptr(), "add_node", type, id_to_use);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "remove_node", type, id_to_use);
VisualShaderNodeExpression *expr = Object::cast_to<VisualShaderNodeExpression>(vsnode.ptr());
if (expr) {
@@ -1488,6 +1705,8 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(_from_slot), visual_shader->get_node(type, to_node)->get_input_port_type(to_slot))) {
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot);
}
}
} else if (from_node != -1 && from_slot != -1) {
@@ -1496,33 +1715,51 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
int _to_slot = 0;
if (visual_shader->is_port_types_compatible(visual_shader->get_node(type, from_node)->get_output_port_type(from_slot), vsnode->get_input_port_type(_to_slot))) {
- undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
}
}
}
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr());
+ if (uniform) {
+ undo_redo->add_do_method(this, "_update_uniforms", true);
+ undo_redo->add_undo_method(this, "_update_uniforms", true);
+ }
+
undo_redo->commit_action();
return vsnode.ptr();
}
void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
+ drag_buffer.push_back({ type, p_node, p_from, p_to });
+ if (!drag_dirty) {
+ call_deferred("_nodes_dragged");
+ }
+ drag_dirty = true;
+}
- updating = true;
- undo_redo->create_action(TTR("Node Moved"));
- undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", type, p_node, p_to);
- undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", type, p_node, p_from);
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+void VisualShaderEditor::_nodes_dragged() {
+ drag_dirty = false;
+
+ undo_redo->create_action(TTR("Node(s) Moved"));
+
+ for (List<DragOp>::Element *E = drag_buffer.front(); E; E = E->next()) {
+ undo_redo->add_do_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().to);
+ undo_redo->add_undo_method(visual_shader.ptr(), "set_node_position", E->get().type, E->get().node, E->get().from);
+ undo_redo->add_do_method(graph_plugin.ptr(), "set_node_position", E->get().type, E->get().node, E->get().to);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "set_node_position", E->get().type, E->get().node, E->get().from);
+ }
+
+ drag_buffer.clear();
undo_redo->commit_action();
- updating = false;
}
void VisualShaderEditor::_connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
int from = p_from.to_int();
int to = p_to.to_int();
@@ -1540,32 +1777,32 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
if (E->get().to_node == to && E->get().to_port == p_to_index) {
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
}
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->commit_action();
}
void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
graph->disconnect_node(p_from, p_from_index, p_to, p_to_index);
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
int from = p_from.to_int();
int to = p_to.to_int();
- //updating = true; seems graph edit can handle this, no need to protect
undo_redo->create_action(TTR("Nodes Disconnected"));
undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->commit_action();
- //updating = false;
}
void VisualShaderEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) {
@@ -1581,12 +1818,22 @@ void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slo
}
void VisualShaderEditor::_delete_request(int which) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
Ref<VisualShaderNode> node = Ref<VisualShaderNode>(visual_shader->get_node(type, which));
undo_redo->create_action(TTR("Delete Node"));
+
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (E->get().from_node == which || E->get().to_node == which) {
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
+ }
+
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_undo_method(graph_plugin.ptr(), "add_node", type, which);
undo_redo->add_do_method(this, "_clear_buffer");
undo_redo->add_undo_method(this, "_clear_buffer");
@@ -1605,22 +1852,31 @@ void VisualShaderEditor::_delete_request(int which) {
undo_redo->add_undo_method(expression, "set_expression", expression->get_expression());
}
- List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
-
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
if (E->get().from_node == which || E->get().to_node == which) {
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
}
+ // delete a node from the graph
+ undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, which);
+
+ VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
+ if (uniform) {
+ undo_redo->add_do_method(this, "_update_uniforms", true);
+ undo_redo->add_undo_method(this, "_update_uniforms", true);
+
+ Set<String> uniform_names;
+ uniform_names.insert(uniform->get_uniform_name());
+
+ _update_uniform_refs(uniform_names);
+ }
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
}
void VisualShaderEditor::_node_selected(Object *p_node) {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
GraphNode *gn = Object::cast_to<GraphNode>(p_node);
ERR_FAIL_COND(!gn);
@@ -1874,12 +2130,13 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in
Ref<VisualShaderNode> dupli = node->duplicate();
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);
+ undo_redo->add_do_method(graph_plugin.ptr(), "add_node", type, id_from);
// duplicate size, inputs and outputs if node is group
Ref<VisualShaderNodeGroupBase> group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr());
if (!group.is_null()) {
undo_redo->add_do_method(dupli.ptr(), "set_size", group->get_size());
+ undo_redo->add_do_method(graph_plugin.ptr(), "set_node_size", type, id_from, group->get_size());
undo_redo->add_do_method(dupli.ptr(), "set_inputs", group->get_inputs());
undo_redo->add_do_method(dupli.ptr(), "set_outputs", group->get_outputs());
}
@@ -1900,12 +2157,19 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in
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);
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port);
}
}
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ id_from = base_id;
+ for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "remove_node", type, id_from);
+ id_from++;
+ }
+
undo_redo->commit_action();
if (p_select) {
@@ -1978,7 +2242,7 @@ void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2
}
void VisualShaderEditor::_delete_nodes() {
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ VisualShader::Type type = get_current_shader_type();
List<int> to_erase;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -1996,11 +2260,25 @@ void VisualShaderEditor::_delete_nodes() {
undo_redo->create_action(TTR("Delete Nodes"));
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+
+ for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (E->get().from_node == F->get() || E->get().to_node == F->get()) {
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
+ }
+ }
+
+ Set<String> uniform_names;
+
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
Ref<VisualShaderNode> node = visual_shader->get_node(type, F->get());
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_undo_method(graph_plugin.ptr(), "add_node", type, F->get());
undo_redo->add_do_method(this, "_clear_buffer");
undo_redo->add_undo_method(this, "_clear_buffer");
@@ -2018,10 +2296,12 @@ void VisualShaderEditor::_delete_nodes() {
if (expression) {
undo_redo->add_undo_method(expression, "set_expression", expression->get_expression());
}
- }
- List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
+ VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
+ if (uniform) {
+ uniform_names.insert(uniform->get_uniform_name());
+ }
+ }
List<VisualShader::Connection> used_conns;
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
@@ -2036,53 +2316,78 @@ void VisualShaderEditor::_delete_nodes() {
}
if (!cancel) {
undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
used_conns.push_back(E->get());
}
}
}
}
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
+ // delete nodes from the graph
+ for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
+ undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F->get());
+ }
+
+ // update uniform refs if any uniform has been deleted
+ if (uniform_names.size() > 0) {
+ undo_redo->add_do_method(this, "_update_uniforms", true);
+ undo_redo->add_undo_method(this, "_update_uniforms", true);
+
+ _update_uniform_refs(uniform_names);
+ }
+
undo_redo->commit_action();
}
void VisualShaderEditor::_mode_selected(int p_id) {
+ visual_shader->set_shader_type(particles_mode ? VisualShader::Type(p_id + 3) : VisualShader::Type(p_id));
_update_options_menu();
_update_graph();
}
-void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> input, String name) {
- String prev_name = input->get_input_name();
+void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input, String p_name) {
+ String prev_name = p_input->get_input_name();
- if (name == prev_name) {
+ if (p_name == prev_name) {
return;
}
- bool type_changed = input->get_input_type_by_name(name) != input->get_input_type_by_name(prev_name);
+ bool type_changed = p_input->get_input_type_by_name(p_name) != p_input->get_input_type_by_name(prev_name);
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Visual Shader Input Type Changed"));
- undo_redo->add_do_method(input.ptr(), "set_input_name", name);
- undo_redo->add_undo_method(input.ptr(), "set_input_name", prev_name);
-
- if (type_changed) {
- //restore connections if type changed
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
- int id = visual_shader->find_node_id(type, input);
- List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
- for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
- if (E->get().from_node == id) {
- undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(p_input.ptr(), "set_input_name", p_name);
+ undo_redo->add_undo_method(p_input.ptr(), "set_input_name", prev_name);
+
+ // update output port
+ for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) {
+ VisualShader::Type type = VisualShader::Type(type_id);
+ int id = visual_shader->find_node_id(type, p_input);
+ if (id != VisualShader::NODE_ID_INVALID) {
+ if (type_changed) {
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (E->get().from_node == id) {
+ if (visual_shader->is_port_types_compatible(p_input->get_input_type_by_name(p_name), visual_shader->get_node(type, E->get().to_node)->get_input_port_type(E->get().to_port))) {
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ continue;
+ }
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
+ }
}
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id);
+ break;
}
}
- undo_redo->add_do_method(VisualShaderEditor::get_singleton(), "_update_graph");
- undo_redo->add_undo_method(VisualShaderEditor::get_singleton(), "_update_graph");
-
undo_redo->commit_action();
}
@@ -2101,23 +2406,32 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_
undo_redo->add_do_method(p_uniform_ref.ptr(), "set_uniform_name", p_name);
undo_redo->add_undo_method(p_uniform_ref.ptr(), "set_uniform_name", prev_name);
- if (type_changed) {
- //restore connections if type changed
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ // update output port
+ for (int type_id = 0; type_id < VisualShader::TYPE_MAX; type_id++) {
+ VisualShader::Type type = VisualShader::Type(type_id);
int id = visual_shader->find_node_id(type, p_uniform_ref);
- List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
- for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
- if (E->get().from_node == id) {
- undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
- undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ if (id != VisualShader::NODE_ID_INVALID) {
+ if (type_changed) {
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (E->get().from_node == id) {
+ if (visual_shader->is_port_types_compatible(p_uniform_ref->get_uniform_type_by_name(p_name), visual_shader->get_node(type, E->get().to_node)->get_input_port_type(E->get().to_port))) {
+ continue;
+ }
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
+ }
}
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, id);
+ break;
}
}
- undo_redo->add_do_method(VisualShaderEditor::get_singleton(), "_update_graph");
- undo_redo->add_undo_method(VisualShaderEditor::get_singleton(), "_update_graph");
-
undo_redo->commit_action();
}
@@ -2340,7 +2654,6 @@ void VisualShaderEditor::_update_preview() {
}
void VisualShaderEditor::_bind_methods() {
- ClassDB::bind_method("_rebuild", &VisualShaderEditor::_rebuild);
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu);
ClassDB::bind_method("_add_node", &VisualShaderEditor::_add_node);
@@ -2349,6 +2662,9 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_uniform_select_item", &VisualShaderEditor::_uniform_select_item);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
+ ClassDB::bind_method("_update_uniforms", &VisualShaderEditor::_update_uniforms);
+ ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode);
+ ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged);
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);
@@ -2428,14 +2744,26 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->add_child(vs);
graph->get_zoom_hbox()->move_child(vs, 0);
- edit_type = memnew(OptionButton);
- edit_type->add_item(TTR("Vertex"));
- edit_type->add_item(TTR("Fragment"));
- edit_type->add_item(TTR("Light"));
- edit_type->select(1);
- edit_type->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
- graph->get_zoom_hbox()->add_child(edit_type);
- graph->get_zoom_hbox()->move_child(edit_type, 0);
+ edit_type_standart = memnew(OptionButton);
+ edit_type_standart->add_item(TTR("Vertex"));
+ edit_type_standart->add_item(TTR("Fragment"));
+ edit_type_standart->add_item(TTR("Light"));
+ edit_type_standart->select(1);
+ edit_type_standart->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
+
+ edit_type_particles = memnew(OptionButton);
+ edit_type_particles->add_item(TTR("Emit"));
+ edit_type_particles->add_item(TTR("Process"));
+ edit_type_particles->add_item(TTR("End"));
+ edit_type_particles->select(0);
+ edit_type_particles->connect("item_selected", callable_mp(this, &VisualShaderEditor::_mode_selected));
+
+ edit_type = edit_type_standart;
+
+ graph->get_zoom_hbox()->add_child(edit_type_particles);
+ graph->get_zoom_hbox()->move_child(edit_type_particles, 0);
+ graph->get_zoom_hbox()->add_child(edit_type_standart);
+ graph->get_zoom_hbox()->move_child(edit_type_standart, 0);
add_node = memnew(Button);
add_node->set_flat(true);
@@ -2458,14 +2786,14 @@ VisualShaderEditor::VisualShaderEditor() {
preview_vbox = memnew(VBoxContainer);
preview_vbox->set_visible(preview_showed);
main_box->add_child(preview_vbox);
- preview_text = memnew(TextEdit);
+ preview_text = memnew(CodeEdit);
syntax_highlighter.instance();
preview_vbox->add_child(preview_text);
preview_text->set_h_size_flags(SIZE_EXPAND_FILL);
preview_text->set_v_size_flags(SIZE_EXPAND_FILL);
preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
preview_text->set_syntax_highlighter(syntax_highlighter);
- preview_text->set_show_line_numbers(true);
+ preview_text->set_draw_line_numbers(true);
preview_text->set_readonly(true);
error_text = memnew(Label);
@@ -2614,6 +2942,7 @@ VisualShaderEditor::VisualShaderEditor() {
// INPUT
// SPATIAL-FOR-ALL
+
const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
@@ -2644,124 +2973,156 @@ VisualShaderEditor::VisualShaderEditor() {
const String input_param_for_fragment_shader_mode = TTR("'%s' input parameter for fragment shader mode.");
const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode.");
const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode.");
+ const String input_param_for_emit_shader_mode = TTR("'%s' input parameter for emit shader mode.");
+ const String input_param_for_process_shader_mode = TTR("'%s' input parameter for process shader mode.");
+ const String input_param_for_end_shader_mode = TTR("'%s' input parameter for end shader mode.");
+ const String input_param_for_emit_and_process_shader_mode = TTR("'%s' input parameter for emit and process shader mode.");
const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode.");
- add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), "depth_texture", VisualShaderNode::PORT_TYPE_SAMPLER, 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("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Side", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "side"), "side", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV2", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
-
- add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Transmission", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "transmission"), "transmission", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
-
- add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV2", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), "depth_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_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, TYPE_FLAGS_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, TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_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, TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV2", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+
+ add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Transmission", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "transmission"), "transmission", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+
+ add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV2", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
// CANVASITEM INPUTS
- add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), "normal_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
-
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightHeight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_height"), "light_height", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_uv"), "light_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightVector", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_vec"), "light_vec", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), "shadow_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ShadowVec", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_vec"), "shadow_vec", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
-
- add_options.push_back(AddOption("Extra", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "extra"), "extra", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Projection", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), "normal_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightHeight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_height"), "light_height", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_uv"), "light_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightVector", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_vec"), "light_vec", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), "shadow_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowVec", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_vec"), "shadow_vec", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+
+ add_options.push_back(AddOption("Extra", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "extra"), "extra", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Projection", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
// PARTICLES INPUTS
- add_options.push_back(AddOption("Active", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Delta", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmissionTransform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("LifeTime", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Restart", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Time", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Transform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Active", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Alpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CustomAlpha", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Delta", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmissionTransform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Index", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("LifeTime", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Restart", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Time", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Transform", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "Emit", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+
+ add_options.push_back(AddOption("Active", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Alpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CustomAlpha", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Delta", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmissionTransform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Index", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("LifeTime", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Restart", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Time", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Transform", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "Process", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+
+ add_options.push_back(AddOption("Active", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Alpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CustomAlpha", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Delta", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmissionTransform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Index", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("LifeTime", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Restart", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Time", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Transform", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "End", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_END, Shader::MODE_PARTICLES));
// SKY INPUTS
- add_options.push_back(AddOption("AtCubeMapPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("AtHalfResPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_half_res_pass"), "at_half_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("AtQuarterResPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_quarter_res_pass"), "at_quarter_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("EyeDir", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "eyedir"), "eyedir", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("HalfResColor", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "half_res_color"), "half_res_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("HalfResAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "half_res_alpha"), "half_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_color"), "light0_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_direction"), "light0_direction", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_enabled"), "light0_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_energy"), "light0_energy", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_color"), "light1_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_direction"), "light1_direction", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_enabled"), "light1_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_energy"), "light1_energy", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_color"), "light2_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_direction"), "light2_direction", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_enabled"), "light2_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_energy"), "light2_energy", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_color"), "light3_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_direction"), "light3_direction", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_enabled"), "light3_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_energy"), "light3_energy", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Position", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "position"), "position", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("QuarterResColor", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "quarter_res_color"), "quarter_res_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("QuarterResAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "quarter_res_alpha"), "quarter_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Radiance", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "radiance"), "radiance", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- 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_SKY));
- add_options.push_back(AddOption("SkyCoords", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
- add_options.push_back(AddOption("Time", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtCubeMapPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtHalfResPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_half_res_pass"), "at_half_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtQuarterResPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "at_quarter_res_pass"), "at_quarter_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("EyeDir", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "eyedir"), "eyedir", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("HalfResColor", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "half_res_color"), "half_res_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("HalfResAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "half_res_alpha"), "half_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_color"), "light0_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_direction"), "light0_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_enabled"), "light0_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light0_energy"), "light0_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_color"), "light1_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_direction"), "light1_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_enabled"), "light1_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light1_energy"), "light1_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_color"), "light2_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_direction"), "light2_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_enabled"), "light2_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light2_energy"), "light2_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_color"), "light3_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Direction", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_direction"), "light3_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Enabled", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_enabled"), "light3_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Energy", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "light3_energy"), "light3_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Position", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "position"), "position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("QuarterResColor", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "quarter_res_color"), "quarter_res_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("QuarterResAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "quarter_res_alpha"), "quarter_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Radiance", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "radiance"), "radiance", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("SkyCoords", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Time", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SKY));
// SCALAR
@@ -2849,12 +3210,15 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
texture_node_option_idx = add_options.size();
- add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, -1));
- add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
+ add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1));
add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1));
+
+ add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1));
- add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup."), -1, -1, -1, -1, -1));
// TRANSFORM
@@ -2951,15 +3315,15 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
add_options.push_back(AddOption("UniformRef", "Special", "", "VisualShaderNodeUniformRef", TTR("A reference to an existing uniform.")));
- 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("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- 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));
+ 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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_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, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
custom_node_option_idx = add_options.size();
/////////////////////////////////////////////////////////////////////
@@ -2979,12 +3343,16 @@ VisualShaderEditor::VisualShaderEditor() {
default_plugin.instance();
add_plugin(default_plugin);
+ graph_plugin.instance();
+
property_editor = memnew(CustomPropertyEditor);
add_child(property_editor);
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
}
+/////////////////
+
void VisualShaderEditorPlugin::edit(Object *p_object) {
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
}
@@ -3119,6 +3487,8 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
Ref<Resource> parent_resource;
+ int node_id;
+ VisualShader::Type shader_type;
public:
void _property_changed(const String &p_property, const Variant &p_value, const String &p_field = "", bool p_changing = false) {
@@ -3147,8 +3517,10 @@ public:
} 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");
+ }
+ if (p_property != "constant") {
+ undo_redo->add_do_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_node_deferred", shader_type, node_id);
+ undo_redo->add_undo_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_node_deferred", shader_type, node_id);
}
undo_redo->commit_action();
@@ -3164,10 +3536,6 @@ public:
}
}
- void _refresh_request() {
- VisualShaderEditor::get_singleton()->call_deferred("_update_graph");
- }
-
void _resource_selected(const String &p_path, RES p_resource) {
_open_inspector(p_resource);
}
@@ -3193,6 +3561,9 @@ public:
node = p_node;
properties = p_properties;
+ node_id = (int)p_node->get_meta("id");
+ shader_type = VisualShader::Type((int)p_node->get_meta("shader_type"));
+
for (int i = 0; i < p_properties.size(); i++) {
HBoxContainer *hbox = memnew(HBoxContainer);
hbox->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -3220,11 +3591,9 @@ public:
properties[i]->set_name_split_ratio(0);
}
node->connect("changed", callable_mp(this, &VisualShaderNodePluginDefaultEditor::_node_changed));
- node->connect("editor_refresh_request", callable_mp(this, &VisualShaderNodePluginDefaultEditor::_refresh_request), varray(), CONNECT_DEFERRED);
}
static void _bind_methods() {
- ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request); // Used by UndoRedo.
ClassDB::bind_method("_open_inspector", &VisualShaderNodePluginDefaultEditor::_open_inspector); // Used by UndoRedo.
ClassDB::bind_method("_show_prop_names", &VisualShaderNodePluginDefaultEditor::_show_prop_names); // Used with call_deferred.
}
@@ -3313,6 +3682,10 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
//do is easy
undo_redo->add_do_method(visual_shader.ptr(), "set_mode", p_which);
undo_redo->add_undo_method(visual_shader.ptr(), "set_mode", visual_shader->get_mode());
+
+ undo_redo->add_do_method(VisualShaderEditor::get_singleton(), "_set_mode", p_which);
+ undo_redo->add_undo_method(VisualShaderEditor::get_singleton(), "_set_mode", visual_shader->get_mode());
+
//now undo is hell
//1. restore connections to output
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 9b80488b22..49d7721ecd 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -50,8 +50,72 @@ public:
virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
+class VisualShaderGraphPlugin : public Reference {
+ GDCLASS(VisualShaderGraphPlugin, Reference);
+
+private:
+ struct InputPort {
+ Button *default_input_button;
+ };
+
+ struct Port {
+ TextureButton *preview_button;
+ };
+
+ struct Link {
+ VisualShader::Type type;
+ VisualShaderNode *visual_node;
+ GraphNode *graph_node;
+ bool preview_visible;
+ int preview_pos;
+ Map<int, InputPort> input_ports;
+ Map<int, Port> output_ports;
+ VBoxContainer *preview_box;
+ LineEdit *uniform_name;
+ };
+
+ Ref<VisualShader> visual_shader;
+ Map<int, Link> links;
+ List<VisualShader::Connection> connections;
+ bool dirty = false;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void register_shader(VisualShader *p_visual_shader);
+ void set_connections(List<VisualShader::Connection> &p_connections);
+ void register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node);
+ void register_output_port(int p_id, int p_port, TextureButton *p_button);
+ void register_uniform_name(int p_id, LineEdit *p_uniform_name);
+ void clear_links();
+ void set_shader_type(VisualShader::Type p_type);
+ bool is_preview_visible(int p_id) const;
+ bool is_dirty() const;
+ void make_dirty(bool p_enabled);
+ void update_node(VisualShader::Type p_type, int p_id);
+ void update_node_deferred(VisualShader::Type p_type, int p_node_id);
+ void add_node(VisualShader::Type p_type, int p_id);
+ void remove_node(VisualShader::Type p_type, int p_id);
+ void connect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+ void disconnect_nodes(VisualShader::Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+ void show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id);
+ void set_node_position(VisualShader::Type p_type, int p_id, const Vector2 &p_position);
+ void set_node_size(VisualShader::Type p_type, int p_id, const Vector2 &p_size);
+ void refresh_node_ports(VisualShader::Type p_type, int p_node);
+ void set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value);
+ void register_default_input_button(int p_node_id, int p_port_id, Button *p_button);
+ void update_uniform_refs();
+ void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name);
+ VisualShader::Type get_shader_type() const;
+
+ VisualShaderGraphPlugin();
+ ~VisualShaderGraphPlugin();
+};
+
class VisualShaderEditor : public VBoxContainer {
GDCLASS(VisualShaderEditor, VBoxContainer);
+ friend class VisualShaderGraphPlugin;
CustomPropertyEditor *property_editor;
int editing_node;
@@ -63,7 +127,9 @@ class VisualShaderEditor : public VBoxContainer {
Button *add_node;
Button *preview_shader;
- OptionButton *edit_type;
+ OptionButton *edit_type = nullptr;
+ OptionButton *edit_type_standart;
+ OptionButton *edit_type_particles;
PanelContainer *error_panel;
Label *error_label;
@@ -71,7 +137,7 @@ class VisualShaderEditor : public VBoxContainer {
bool pending_update_preview;
bool shader_error;
VBoxContainer *preview_vbox;
- TextEdit *preview_text;
+ CodeEdit *preview_text;
Ref<CodeHighlighter> syntax_highlighter;
Label *error_text;
@@ -84,6 +150,19 @@ class VisualShaderEditor : public VBoxContainer {
MenuButton *tools;
bool preview_showed;
+ bool particles_mode;
+
+ enum TypeFlags {
+ TYPE_FLAGS_VERTEX = 1,
+ TYPE_FLAGS_FRAGMENT = 2,
+ TYPE_FLAGS_LIGHT = 4,
+ };
+
+ enum ParticlesTypeFlags {
+ TYPE_FLAGS_EMIT = 1,
+ TYPE_FLAGS_PROCESS = 2,
+ TYPE_FLAGS_END = 4
+ };
enum ToolsMenuOptions {
EXPAND_ALL,
@@ -166,12 +245,15 @@ class VisualShaderEditor : public VBoxContainer {
int custom_node_option_idx;
List<String> keyword_list;
+ List<VisualShaderNodeUniformRef> uniform_refs;
+
void _draw_color_over_button(Object *obj, Color p_color);
void _add_custom_node(const String &p_path);
void _add_texture_node(const String &p_path);
VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1);
void _update_options_menu();
+ void _set_mode(int p_which);
void _show_preview_text();
void _update_preview();
@@ -179,7 +261,16 @@ class VisualShaderEditor : public VBoxContainer {
static VisualShaderEditor *singleton;
+ struct DragOp {
+ VisualShader::Type type;
+ int node;
+ Vector2 from;
+ Vector2 to;
+ };
+ List<DragOp> drag_buffer;
+ bool drag_dirty = false;
void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
+ void _nodes_dragged();
bool updating;
void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index);
@@ -206,8 +297,8 @@ class VisualShaderEditor : public VBoxContainer {
void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position);
void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position);
- void _line_edit_changed(const String &p_text, Object *line_edit, int p_node_id);
- void _line_edit_focus_out(Object *line_edit, int p_node_id);
+ void _uniform_line_edit_changed(const String &p_text, int p_node_id);
+ void _uniform_line_edit_focus_out(Object *line_edit, int p_node_id);
void _port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output);
@@ -227,13 +318,15 @@ class VisualShaderEditor : public VBoxContainer {
void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2());
Vector<Ref<VisualShaderNodePlugin>> plugins;
+ Ref<VisualShaderGraphPlugin> graph_plugin;
void _mode_selected(int p_id);
- void _rebuild();
void _input_select_item(Ref<VisualShaderNodeInput> input, String name);
void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name);
+ VisualShader::Type get_current_shader_type() const;
+
void _add_input_port(int p_node, int p_port, int p_port_type, const String &p_name);
void _remove_input_port(int p_node, int p_port);
void _change_input_port_type(int p_type, int p_node, int p_port);
@@ -244,7 +337,7 @@ class VisualShaderEditor : public VBoxContainer {
void _change_output_port_type(int p_type, int p_node, int p_port);
void _change_output_port_name(const String &p_text, Object *line_edit, int p_node, int p_port);
- void _expression_focus_out(Object *text_edit, int p_node);
+ void _expression_focus_out(Object *code_edit, int p_node);
void _set_node_size(int p_type, int p_node, const Size2 &p_size);
void _node_resized(const Vector2 &p_new_size, int p_type, int p_node);
@@ -268,6 +361,8 @@ class VisualShaderEditor : public VBoxContainer {
bool _is_available(int p_mode);
void _update_created_node(GraphNode *node);
+ void _update_uniforms(bool p_update_refs);
+ void _update_uniform_refs(Set<String> &p_names);
protected:
void _notification(int p_what);
@@ -279,6 +374,7 @@ public:
void remove_plugin(const Ref<VisualShaderNodePlugin> &p_plugin);
static VisualShaderEditor *get_singleton() { return singleton; }
+ VisualShaderGraphPlugin *get_graph_plugin() { return graph_plugin.ptr(); }
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, bool p_highend);
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index f45161d87b..1f553ba0de 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -310,6 +310,24 @@ void ProjectExportDialog::_edit_preset(int p_index) {
_update_export_all();
child_controls_changed();
+ String enc_in_filters_str = current->get_enc_in_filter();
+ String enc_ex_filters_str = current->get_enc_ex_filter();
+ if (!updating_enc_filters) {
+ enc_in_filters->set_text(enc_in_filters_str);
+ enc_ex_filters->set_text(enc_ex_filters_str);
+ }
+
+ bool enc_pck_mode = current->get_enc_pck();
+ enc_pck->set_pressed(enc_pck_mode);
+
+ enc_directory->set_disabled(!enc_pck_mode);
+ enc_in_filters->set_editable(enc_pck_mode);
+ enc_ex_filters->set_editable(enc_pck_mode);
+ script_key->set_editable(enc_pck_mode);
+
+ bool enc_directory_mode = current->get_enc_directory();
+ enc_directory->set_pressed(enc_directory_mode);
+
int script_export_mode = current->get_script_export_mode();
script_mode->select(script_export_mode);
@@ -317,7 +335,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
if (!updating_script_key) {
script_key->set_text(key);
}
- if (script_export_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) {
+ if (enc_pck_mode) {
script_key->set_editable(true);
bool key_valid = _validate_script_encryption_key(key);
@@ -519,6 +537,56 @@ void ProjectExportDialog::_export_path_changed(const StringName &p_property, con
_update_presets();
}
+void ProjectExportDialog::_enc_filters_changed(const String &p_filters) {
+ if (updating) {
+ return;
+ }
+
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ current->set_enc_in_filter(enc_in_filters->get_text());
+ current->set_enc_ex_filter(enc_ex_filters->get_text());
+
+ updating_enc_filters = true;
+ _update_current_preset();
+ updating_enc_filters = false;
+}
+
+void ProjectExportDialog::_open_key_help_link() {
+ OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/development/compiling/compiling_with_script_encryption_key.html");
+}
+
+void ProjectExportDialog::_enc_pck_changed(bool p_pressed) {
+ if (updating) {
+ return;
+ }
+
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ current->set_enc_pck(p_pressed);
+ enc_directory->set_disabled(!p_pressed);
+ enc_in_filters->set_editable(p_pressed);
+ enc_ex_filters->set_editable(p_pressed);
+ script_key->set_editable(p_pressed);
+
+ _update_current_preset();
+}
+
+void ProjectExportDialog::_enc_directory_changed(bool p_pressed) {
+ if (updating) {
+ return;
+ }
+
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ current->set_enc_directory(p_pressed);
+
+ _update_current_preset();
+}
+
void ProjectExportDialog::_script_export_mode_changed(int p_mode) {
if (updating) {
return;
@@ -1148,6 +1216,12 @@ ProjectExportDialog::ProjectExportDialog() {
exclude_filters);
exclude_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_filter_changed));
+ script_mode = memnew(OptionButton);
+ resources_vb->add_margin_child(TTR("Script Export Mode:"), script_mode);
+ script_mode->add_item(TTR("Text"), (int)EditorExportPreset::MODE_SCRIPT_TEXT);
+ script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED);
+ script_mode->connect("item_selected", callable_mp(this, &ProjectExportDialog::_script_export_mode_changed));
+
// Patch packages.
VBoxContainer *patch_vb = memnew(VBoxContainer);
@@ -1205,23 +1279,50 @@ ProjectExportDialog::ProjectExportDialog() {
// Script export parameters.
updating_script_key = false;
+ updating_enc_filters = false;
+
+ VBoxContainer *sec_vb = memnew(VBoxContainer);
+ sec_vb->set_name(TTR("Encryption"));
+
+ enc_pck = memnew(CheckButton);
+ enc_pck->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_pck_changed));
+ enc_pck->set_text(TTR("Encrypt exported PCK"));
+ sec_vb->add_child(enc_pck);
+
+ enc_directory = memnew(CheckButton);
+ enc_directory->connect("toggled", callable_mp(this, &ProjectExportDialog::_enc_directory_changed));
+ enc_directory->set_text("Encrypt index (file names and info).");
+ sec_vb->add_child(enc_directory);
+
+ enc_in_filters = memnew(LineEdit);
+ enc_in_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_enc_filters_changed));
+ sec_vb->add_margin_child(
+ TTR("Filters to include files/folders\n(comma-separated, e.g: *.tscn, *.tres, scenes/*)"),
+ enc_in_filters);
+
+ enc_ex_filters = memnew(LineEdit);
+ enc_ex_filters->connect("text_changed", callable_mp(this, &ProjectExportDialog::_enc_filters_changed));
+ sec_vb->add_margin_child(
+ TTR("Filters to exclude files/folders\n(comma-separated, e.g: *.stex, *.import, music/*)"),
+ enc_ex_filters);
- VBoxContainer *script_vb = memnew(VBoxContainer);
- script_vb->set_name(TTR("Script"));
- script_mode = memnew(OptionButton);
- script_vb->add_margin_child(TTR("Script Export Mode:"), script_mode);
- script_mode->add_item(TTR("Text"), (int)EditorExportPreset::MODE_SCRIPT_TEXT);
- script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED);
- script_mode->add_item(TTR("Encrypted (Provide Key Below)"), (int)EditorExportPreset::MODE_SCRIPT_ENCRYPTED);
- script_mode->connect("item_selected", callable_mp(this, &ProjectExportDialog::_script_export_mode_changed));
script_key = memnew(LineEdit);
script_key->connect("text_changed", callable_mp(this, &ProjectExportDialog::_script_encryption_key_changed));
script_key_error = memnew(Label);
script_key_error->set_text("- " + TTR("Invalid Encryption Key (must be 64 characters long)"));
script_key_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor"));
- script_vb->add_margin_child(TTR("Script Encryption Key (256-bits as hex):"), script_key);
- script_vb->add_child(script_key_error);
- sections->add_child(script_vb);
+ sec_vb->add_margin_child(TTR("Encryption Key (256-bits as hex):"), script_key);
+ sec_vb->add_child(script_key_error);
+ sections->add_child(sec_vb);
+
+ Label *sec_info = memnew(Label);
+ sec_info->set_text(TTR("Note: Encryption key needs to be stored in the binary,\nyou need to build the export templates from source."));
+ sec_vb->add_child(sec_info);
+
+ LinkButton *sec_more_info = memnew(LinkButton);
+ sec_more_info->set_text(TTR("More Info..."));
+ sec_more_info->connect("pressed", callable_mp(this, &ProjectExportDialog::_open_key_help_link));
+ sec_vb->add_child(sec_more_info);
sections->connect("tab_changed", callable_mp(this, &ProjectExportDialog::_tab_changed));
diff --git a/editor/project_export.h b/editor/project_export.h
index cfa00773d8..75402dc334 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -145,6 +145,11 @@ private:
CheckBox *export_debug;
CheckBox *export_pck_zip_debug;
+ CheckButton *enc_pck;
+ CheckButton *enc_directory;
+ LineEdit *enc_in_filters;
+ LineEdit *enc_ex_filters;
+
void _open_export_template_manager();
void _export_pck_zip();
@@ -161,10 +166,16 @@ private:
void _custom_features_changed(const String &p_text);
bool updating_script_key;
+ bool updating_enc_filters;
+ void _enc_pck_changed(bool p_pressed);
+ void _enc_directory_changed(bool p_pressed);
+ void _enc_filters_changed(const String &p_text);
void _script_export_mode_changed(int p_mode);
void _script_encryption_key_changed(const String &p_key);
bool _validate_script_encryption_key(const String &p_key);
+ void _open_key_help_link();
+
void _tab_changed(int);
protected:
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 35311b32eb..1fb889d793 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -330,6 +330,7 @@ private:
return;
}
}
+
String sp = p.simplify_path();
project_path->set_text(sp);
_path_text_changed(sp);
@@ -411,7 +412,7 @@ private:
_test_path();
if (p_text == "") {
- set_message(TTR("It would be a good idea to name your project."), MESSAGE_WARNING);
+ set_message(TTR("It would be a good idea to name your project."), MESSAGE_ERROR);
}
}
@@ -1012,7 +1013,7 @@ public:
void update_dock_menu();
void load_projects();
void set_search_term(String p_search_term);
- void set_order_option(ProjectListFilter::FilterOption p_option);
+ void set_order_option(int p_option);
void sort_projects();
int get_project_count() const;
void select_project(int p_index);
@@ -1045,7 +1046,7 @@ private:
static void load_project_data(const String &p_property_key, Item &p_item, bool p_favorite);
String _search_term;
- ProjectListFilter::FilterOption _order_option;
+ FilterOption _order_option;
Set<String> _selected_project_keys;
String _last_clicked; // Project key
VBoxContainer *_scroll_children;
@@ -1055,7 +1056,7 @@ private:
};
struct ProjectListComparator {
- ProjectListFilter::FilterOption order_option;
+ FilterOption order_option;
// operator<
_FORCE_INLINE_ bool operator()(const ProjectList::Item &a, const ProjectList::Item &b) const {
@@ -1066,9 +1067,9 @@ struct ProjectListComparator {
return false;
}
switch (order_option) {
- case ProjectListFilter::FILTER_PATH:
+ case PATH:
return a.project_key < b.project_key;
- case ProjectListFilter::FILTER_EDIT_DATE:
+ case EDIT_DATE:
return a.last_edited > b.last_edited;
default:
return a.project_name < b.project_name;
@@ -1077,8 +1078,7 @@ struct ProjectListComparator {
};
ProjectList::ProjectList() {
- _order_option = ProjectListFilter::FILTER_EDIT_DATE;
-
+ _order_option = FilterOption::NAME;
_scroll_children = memnew(VBoxContainer);
_scroll_children->set_h_size_flags(Control::SIZE_EXPAND_FILL);
add_child(_scroll_children);
@@ -1238,8 +1238,6 @@ void ProjectList::load_projects() {
create_project_item_control(i);
}
- sort_projects();
-
set_v_scroll(0);
update_icons_async();
@@ -1391,12 +1389,13 @@ void ProjectList::set_search_term(String p_search_term) {
_search_term = p_search_term;
}
-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();
- }
+void ProjectList::set_order_option(int p_option) {
+ FilterOption selected = (FilterOption)p_option;
+ EditorSettings::get_singleton()->set("project_manager/sorting_order", p_option);
+ EditorSettings::get_singleton()->save();
+ _order_option = selected;
+
+ sort_projects();
}
void ProjectList::sort_projects() {
@@ -1798,6 +1797,9 @@ void ProjectList::_bind_methods() {
void ProjectManager::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ search_box->set_right_icon(get_theme_icon("Search", "EditorIcons"));
+ search_box->set_clear_button_enabled(true);
+
Engine::get_singleton()->set_editor_hint(false);
} break;
case NOTIFICATION_RESIZED: {
@@ -1806,6 +1808,10 @@ void ProjectManager::_notification(int p_what) {
}
} break;
case NOTIFICATION_READY: {
+ int default_sorting = (int)EditorSettings::get_singleton()->get("project_manager/sorting_order");
+ filter_option->select(default_sorting);
+ _project_list->set_order_option(default_sorting);
+
if (_project_list->get_project_count() == 0 && StreamPeerSSL::is_available()) {
open_templates->popup_centered();
}
@@ -1813,7 +1819,7 @@ void ProjectManager::_notification(int p_what) {
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();
+ search_box->grab_focus();
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
@@ -1833,7 +1839,7 @@ void ProjectManager::_dim_window() {
// 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);
+ set_modulate(dim_color);
}
void ProjectManager::_update_project_buttons() {
@@ -1853,7 +1859,7 @@ void ProjectManager::_update_project_buttons() {
rename_btn->set_disabled(empty_selection || is_missing_project_selected);
run_btn->set_disabled(empty_selection || is_missing_project_selected);
- erase_missing_btn->set_visible(_project_list->is_any_project_missing());
+ erase_missing_btn->set_disabled(!_project_list->is_any_project_missing());
}
void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
@@ -1930,7 +1936,7 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
} break;
case KEY_F: {
if (k->get_command()) {
- this->project_filter->search_box->grab_focus();
+ this->search_box->grab_focus();
} else {
keycode_handled = false;
}
@@ -1947,8 +1953,7 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
}
void ProjectManager::_load_recent_projects() {
- _project_list->set_order_option(project_order_filter->get_filter_option());
- _project_list->set_search_term(project_filter->get_search_term());
+ _project_list->set_search_term(search_box->get_text().strip_edges());
_project_list->load_projects();
_update_project_buttons();
@@ -1970,7 +1975,7 @@ void ProjectManager::_on_projects_updated() {
}
void ProjectManager::_on_project_created(const String &dir) {
- project_filter->clear();
+ search_box->clear();
int i = _project_list->refresh_project(dir);
_project_list->select_project(i);
_project_list->ensure_project_visible(i);
@@ -2113,7 +2118,6 @@ 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();
@@ -2226,8 +2230,6 @@ void ProjectManager::_erase_missing_projects() {
void ProjectManager::_language_selected(int p_id) {
String lang = language_btn->get_item_metadata(p_id);
EditorSettings::get_singleton()->set("interface/editor/editor_language", lang);
- language_btn->set_text(lang);
- language_btn->set_icon(get_theme_icon("Environment", "EditorIcons"));
language_restart_ask->set_text(TTR("Language changed.\nThe interface will update after restarting the editor or project manager."));
language_restart_ask->popup_centered();
@@ -2304,13 +2306,14 @@ void ProjectManager::_scan_multiple_folders(PackedStringArray 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_order_option_changed(int p_idx) {
+ if (is_inside_tree()) {
+ _project_list->set_order_option(p_idx);
+ }
}
-void ProjectManager::_on_filter_option_changed() {
- _project_list->set_search_term(project_filter->get_search_term());
+void ProjectManager::_on_search_term_changed(const String &p_term) {
+ _project_list->set_search_term(p_term);
_project_list->sort_projects();
// Select the first visible project in the list.
@@ -2341,7 +2344,6 @@ ProjectManager::ProjectManager() {
{
int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale");
- float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale");
switch (display_scale) {
case 0: {
@@ -2372,9 +2374,8 @@ ProjectManager::ProjectManager() {
case 6:
editor_set_scale(2.0);
break;
-
default: {
- editor_set_scale(custom_display_scale);
+ editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale"));
} break;
}
@@ -2385,28 +2386,27 @@ ProjectManager::ProjectManager() {
DisplayServer::get_singleton()->window_set_size(DisplayServer::get_singleton()->window_get_size() * MAX(1, EDSCALE));
}
+ String cp;
+ cp += 0xA9;
+ // TRANSLATORS: This refers to the application where users manage their Godot projects.
+ DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
+
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
set_anchors_and_margins_preset(Control::PRESET_WIDE);
set_theme(create_custom_theme());
- gui_base = memnew(Control);
- add_child(gui_base);
- gui_base->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ set_anchors_and_margins_preset(Control::PRESET_WIDE);
Panel *panel = memnew(Panel);
- gui_base->add_child(panel);
+ add_child(panel);
panel->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- panel->add_theme_style_override("panel", gui_base->get_theme_stylebox("Background", "EditorStyles"));
+ panel->add_theme_style_override("panel", get_theme_stylebox("Background", "EditorStyles"));
VBoxContainer *vb = memnew(VBoxContainer);
panel->add_child(vb);
vb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE);
- String cp;
- cp += 0xA9;
- DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
-
Control *center_box = memnew(Control);
center_box->set_v_size_flags(Control::SIZE_EXPAND_FILL);
vb->add_child(center_box);
@@ -2416,218 +2416,231 @@ ProjectManager::ProjectManager() {
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;
-
+ HBoxContainer *projects_hb = memnew(HBoxContainer);
projects_hb->set_name(TTR("Projects"));
+ tabs->add_child(projects_hb);
- tabs->add_child(tree_hb);
-
- VBoxContainer *search_tree_vb = memnew(VBoxContainer);
- tree_hb->add_child(search_tree_vb);
- search_tree_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
-
- HBoxContainer *sort_filters = memnew(HBoxContainer);
- Label *sort_label = memnew(Label);
- sort_label->set_text(TTR("Sort:"));
- sort_filters->add_child(sort_label);
- Vector<String> sort_filter_titles;
- sort_filter_titles.push_back(TTR("Name"));
- sort_filter_titles.push_back(TTR("Path"));
- sort_filter_titles.push_back(TTR("Last Edited"));
- 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", callable_mp(this, &ProjectManager::_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);
-
- project_filter = memnew(ProjectListFilter);
- project_filter->add_search_box();
- project_filter->connect("filter_changed", callable_mp(this, &ProjectManager::_on_filter_option_changed));
- project_filter->set_custom_minimum_size(Size2(280, 10) * EDSCALE);
- sort_filters->add_child(project_filter);
-
- search_tree_vb->add_child(sort_filters);
-
- PanelContainer *pc = memnew(PanelContainer);
- pc->add_theme_style_override("panel", gui_base->get_theme_stylebox("bg", "Tree"));
- search_tree_vb->add_child(pc);
- pc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- _project_list = memnew(ProjectList);
- _project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
- _project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, callable_mp(this, &ProjectManager::_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);
-
- Button *open = memnew(Button);
- open->set_text(TTR("Edit"));
- tree_vb->add_child(open);
- open->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects_ask));
- open_btn = open;
-
- Button *run = memnew(Button);
- run->set_text(TTR("Run"));
- tree_vb->add_child(run);
- run->connect("pressed", callable_mp(this, &ProjectManager::_run_project));
- run_btn = run;
-
- tree_vb->add_child(memnew(HSeparator));
-
- Button *scan = memnew(Button);
- scan->set_text(TTR("Scan"));
- tree_vb->add_child(scan);
- scan->connect("pressed", callable_mp(this, &ProjectManager::_scan_projects));
-
- tree_vb->add_child(memnew(HSeparator));
-
- scan_dir = memnew(FileDialog);
- scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM);
- scan_dir->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR);
- scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden
- scan_dir->set_current_dir(EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"));
- gui_base->add_child(scan_dir);
- scan_dir->connect("dir_selected", callable_mp(this, &ProjectManager::_scan_begin));
-
- Button *create = memnew(Button);
- create->set_text(TTR("New Project"));
- tree_vb->add_child(create);
- create->connect("pressed", callable_mp(this, &ProjectManager::_new_project));
-
- Button *import = memnew(Button);
- import->set_text(TTR("Import"));
- tree_vb->add_child(import);
- import->connect("pressed", callable_mp(this, &ProjectManager::_import_project));
-
- Button *rename = memnew(Button);
- rename->set_text(TTR("Rename"));
- tree_vb->add_child(rename);
- rename->connect("pressed", callable_mp(this, &ProjectManager::_rename_project));
- rename_btn = rename;
-
- Button *erase = memnew(Button);
- erase->set_text(TTR("Remove"));
- tree_vb->add_child(erase);
- erase->connect("pressed", callable_mp(this, &ProjectManager::_erase_project));
- erase_btn = erase;
-
- Button *erase_missing = memnew(Button);
- erase_missing->set_text(TTR("Remove Missing"));
- tree_vb->add_child(erase_missing);
- erase_missing->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects));
- erase_missing_btn = erase_missing;
-
- tree_vb->add_spacer();
+ {
+ // Projects + search bar
+ VBoxContainer *search_tree_vb = memnew(VBoxContainer);
+ projects_hb->add_child(search_tree_vb);
+ search_tree_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- if (StreamPeerSSL::is_available()) {
- asset_library = memnew(EditorAssetLibrary(true));
- asset_library->set_name(TTR("Templates"));
- tabs->add_child(asset_library);
- asset_library->connect("install_asset", callable_mp(this, &ProjectManager::_install_project));
- } else {
- WARN_PRINT("Asset Library not available, as it requires SSL to work.");
- }
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ search_tree_vb->add_child(hb);
- HBoxContainer *settings_hb = memnew(HBoxContainer);
- settings_hb->set_alignment(BoxContainer::ALIGN_END);
- settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
+ search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Search"));
+ search_box->set_tooltip(TTR("The search box filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character."));
+ search_box->connect("text_changed", callable_mp(this, &ProjectManager::_on_search_term_changed));
+ search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hb->add_child(search_box);
- 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);
+ hb->add_spacer();
- language_btn = memnew(OptionButton);
- language_btn->set_flat(true);
- language_btn->set_focus_mode(Control::FOCUS_NONE);
+ Label *sort_label = memnew(Label);
+ sort_label->set_text(TTR("Sort:"));
+ hb->add_child(sort_label);
- Vector<String> editor_languages;
- List<PropertyInfo> editor_settings_properties;
- EditorSettings::get_singleton()->get_property_list(&editor_settings_properties);
- for (List<PropertyInfo>::Element *E = editor_settings_properties.front(); E; E = E->next()) {
- PropertyInfo &pi = E->get();
- if (pi.name == "interface/editor/editor_language") {
- editor_languages = pi.hint_string.split(",");
- }
- }
- String current_lang = EditorSettings::get_singleton()->get("interface/editor/editor_language");
- for (int i = 0; i < editor_languages.size(); i++) {
- String lang = editor_languages[i];
- String lang_name = TranslationServer::get_singleton()->get_locale_name(lang);
- language_btn->add_item(lang_name + " [" + lang + "]", i);
- language_btn->set_item_metadata(i, lang);
- if (current_lang == lang) {
- language_btn->select(i);
- language_btn->set_text(lang);
- }
- }
- language_btn->set_icon(get_theme_icon("Environment", "EditorIcons"));
+ filter_option = memnew(OptionButton);
+ filter_option->set_clip_text(true);
+ filter_option->set_custom_minimum_size(Size2(150 * EDSCALE, 10 * EDSCALE));
+ filter_option->connect("item_selected", callable_mp(this, &ProjectManager::_on_order_option_changed));
+ hb->add_child(filter_option);
- settings_hb->add_child(language_btn);
- language_btn->connect("item_selected", callable_mp(this, &ProjectManager::_language_selected));
+ Vector<String> sort_filter_titles;
+ sort_filter_titles.push_back(TTR("Name"));
+ sort_filter_titles.push_back(TTR("Path"));
+ sort_filter_titles.push_back(TTR("Last Edited"));
- center_box->add_child(settings_hb);
- settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT);
+ for (int i = 0; i < sort_filter_titles.size(); i++) {
+ filter_option->add_item(sort_filter_titles[i]);
+ }
- //////////////////////////////////////////////////////////////
+ PanelContainer *pc = memnew(PanelContainer);
+ pc->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
+ pc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ search_tree_vb->add_child(pc);
- language_restart_ask = memnew(ConfirmationDialog);
- language_restart_ask->get_ok()->set_text(TTR("Restart Now"));
- language_restart_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_restart_confirm));
- language_restart_ask->get_cancel()->set_text(TTR("Continue"));
- gui_base->add_child(language_restart_ask);
+ _project_list = memnew(ProjectList);
+ _project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, callable_mp(this, &ProjectManager::_update_project_buttons));
+ _project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, callable_mp(this, &ProjectManager::_open_selected_projects_ask));
+ _project_list->set_enable_h_scroll(false);
+ pc->add_child(_project_list);
+ }
- erase_missing_ask = memnew(ConfirmationDialog);
- erase_missing_ask->get_ok()->set_text(TTR("Remove All"));
- erase_missing_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects_confirm));
- gui_base->add_child(erase_missing_ask);
+ {
+ // Project tab side bar
+ VBoxContainer *tree_vb = memnew(VBoxContainer);
+ tree_vb->set_custom_minimum_size(Size2(120, 120));
+ projects_hb->add_child(tree_vb);
+
+ Button *create = memnew(Button);
+ create->set_text(TTR("New Project"));
+ create->connect("pressed", callable_mp(this, &ProjectManager::_new_project));
+ tree_vb->add_child(create);
+
+ Button *import = memnew(Button);
+ import->set_text(TTR("Import"));
+ import->connect("pressed", callable_mp(this, &ProjectManager::_import_project));
+ tree_vb->add_child(import);
+
+ Button *scan = memnew(Button);
+ scan->set_text(TTR("Scan"));
+ scan->connect("pressed", callable_mp(this, &ProjectManager::_scan_projects));
+ tree_vb->add_child(scan);
+
+ tree_vb->add_child(memnew(HSeparator));
+
+ open_btn = memnew(Button);
+ open_btn->set_text(TTR("Edit"));
+ open_btn->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects_ask));
+ tree_vb->add_child(open_btn);
+
+ run_btn = memnew(Button);
+ run_btn->set_text(TTR("Run"));
+ run_btn->connect("pressed", callable_mp(this, &ProjectManager::_run_project));
+ tree_vb->add_child(run_btn);
+
+ rename_btn = memnew(Button);
+ rename_btn->set_text(TTR("Rename"));
+ rename_btn->connect("pressed", callable_mp(this, &ProjectManager::_rename_project));
+ tree_vb->add_child(rename_btn);
+
+ erase_btn = memnew(Button);
+ erase_btn->set_text(TTR("Remove"));
+ erase_btn->connect("pressed", callable_mp(this, &ProjectManager::_erase_project));
+ tree_vb->add_child(erase_btn);
+
+ erase_missing_btn = memnew(Button);
+ erase_missing_btn->set_text(TTR("Remove Missing"));
+ erase_missing_btn->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects));
+ tree_vb->add_child(erase_missing_btn);
+ }
- erase_ask = memnew(ConfirmationDialog);
- erase_ask->get_ok()->set_text(TTR("Remove"));
- erase_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_erase_project_confirm));
- gui_base->add_child(erase_ask);
+ {
+ // Version info and language options
+ HBoxContainer *settings_hb = memnew(HBoxContainer);
+ 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);
+ 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_icon(get_theme_icon("Environment", "EditorIcons"));
+ language_btn->set_focus_mode(Control::FOCUS_NONE);
+ language_btn->connect("item_selected", callable_mp(this, &ProjectManager::_language_selected));
+
+ Vector<String> editor_languages;
+ List<PropertyInfo> editor_settings_properties;
+ EditorSettings::get_singleton()->get_property_list(&editor_settings_properties);
+ for (List<PropertyInfo>::Element *E = editor_settings_properties.front(); E; E = E->next()) {
+ PropertyInfo &pi = E->get();
+ if (pi.name == "interface/editor/editor_language") {
+ editor_languages = pi.hint_string.split(",");
+ break;
+ }
+ }
- multi_open_ask = memnew(ConfirmationDialog);
- multi_open_ask->get_ok()->set_text(TTR("Edit"));
- multi_open_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects));
- gui_base->add_child(multi_open_ask);
+ String current_lang = EditorSettings::get_singleton()->get("interface/editor/editor_language");
+ language_btn->set_text(current_lang);
- multi_run_ask = memnew(ConfirmationDialog);
- multi_run_ask->get_ok()->set_text(TTR("Run"));
- multi_run_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_run_project_confirm));
- gui_base->add_child(multi_run_ask);
+ for (int i = 0; i < editor_languages.size(); i++) {
+ String lang = editor_languages[i];
+ String lang_name = TranslationServer::get_singleton()->get_locale_name(lang);
+ language_btn->add_item(lang_name + " [" + lang + "]", i);
+ language_btn->set_item_metadata(i, lang);
+ if (current_lang == lang) {
+ language_btn->select(i);
+ }
+ }
- multi_scan_ask = memnew(ConfirmationDialog);
- multi_scan_ask->get_ok()->set_text(TTR("Scan"));
- gui_base->add_child(multi_scan_ask);
+ settings_hb->add_child(language_btn);
+ center_box->add_child(settings_hb);
+ settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT);
+ }
- ask_update_settings = memnew(ConfirmationDialog);
- ask_update_settings->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_confirm_update_settings));
- gui_base->add_child(ask_update_settings);
+ if (StreamPeerSSL::is_available()) {
+ asset_library = memnew(EditorAssetLibrary(true));
+ asset_library->set_name(TTR("Templates"));
+ tabs->add_child(asset_library);
+ asset_library->connect("install_asset", callable_mp(this, &ProjectManager::_install_project));
+ } else {
+ WARN_PRINT("Asset Library not available, as it requires SSL to work.");
+ }
- OS::get_singleton()->set_low_processor_usage_mode(true);
+ {
+ // Dialogs
+ language_restart_ask = memnew(ConfirmationDialog);
+ language_restart_ask->get_ok()->set_text(TTR("Restart Now"));
+ language_restart_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_restart_confirm));
+ language_restart_ask->get_cancel()->set_text(TTR("Continue"));
+ add_child(language_restart_ask);
+
+ scan_dir = memnew(FileDialog);
+ scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM);
+ scan_dir->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR);
+ scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden
+ scan_dir->set_current_dir(EditorSettings::get_singleton()->get("filesystem/directories/default_project_path"));
+ add_child(scan_dir);
+ scan_dir->connect("dir_selected", callable_mp(this, &ProjectManager::_scan_begin));
+
+ erase_missing_ask = memnew(ConfirmationDialog);
+ erase_missing_ask->get_ok()->set_text(TTR("Remove All"));
+ erase_missing_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_erase_missing_projects_confirm));
+ add_child(erase_missing_ask);
+
+ erase_ask = memnew(ConfirmationDialog);
+ erase_ask->get_ok()->set_text(TTR("Remove"));
+ erase_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_erase_project_confirm));
+ add_child(erase_ask);
+
+ multi_open_ask = memnew(ConfirmationDialog);
+ multi_open_ask->get_ok()->set_text(TTR("Edit"));
+ multi_open_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects));
+ add_child(multi_open_ask);
+
+ multi_run_ask = memnew(ConfirmationDialog);
+ multi_run_ask->get_ok()->set_text(TTR("Run"));
+ multi_run_ask->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_run_project_confirm));
+ add_child(multi_run_ask);
+
+ multi_scan_ask = memnew(ConfirmationDialog);
+ multi_scan_ask->get_ok()->set_text(TTR("Scan"));
+ add_child(multi_scan_ask);
+
+ ask_update_settings = memnew(ConfirmationDialog);
+ ask_update_settings->get_ok()->connect("pressed", callable_mp(this, &ProjectManager::_confirm_update_settings));
+ add_child(ask_update_settings);
+
+ npdialog = memnew(ProjectDialog);
+ npdialog->connect("projects_updated", callable_mp(this, &ProjectManager::_on_projects_updated));
+ npdialog->connect("project_created", callable_mp(this, &ProjectManager::_on_project_created));
+ add_child(npdialog);
+
+ run_error_diag = memnew(AcceptDialog);
+ run_error_diag->set_title(TTR("Can't run project"));
+ add_child(run_error_diag);
- npdialog = memnew(ProjectDialog);
- gui_base->add_child(npdialog);
+ dialog_error = memnew(AcceptDialog);
+ add_child(dialog_error);
- npdialog->connect("projects_updated", callable_mp(this, &ProjectManager::_on_projects_updated));
- npdialog->connect("project_created", callable_mp(this, &ProjectManager::_on_project_created));
+ open_templates = memnew(ConfirmationDialog);
+ open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?"));
+ open_templates->get_ok()->set_text(TTR("Open Asset Library"));
+ open_templates->connect("confirmed", callable_mp(this, &ProjectManager::_open_asset_library));
+ add_child(open_templates);
+ }
_load_recent_projects();
@@ -2637,18 +2650,7 @@ ProjectManager::ProjectManager() {
SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
- run_error_diag = memnew(AcceptDialog);
- gui_base->add_child(run_error_diag);
- run_error_diag->set_title(TTR("Can't run project"));
-
- dialog_error = memnew(AcceptDialog);
- gui_base->add_child(dialog_error);
-
- open_templates = memnew(ConfirmationDialog);
- open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?"));
- open_templates->get_ok()->set_text(TTR("Open Asset Library"));
- open_templates->connect("confirmed", callable_mp(this, &ProjectManager::_open_asset_library));
- add_child(open_templates);
+ OS::get_singleton()->set_low_processor_usage_mode(true);
}
ProjectManager::~ProjectManager() {
@@ -2656,82 +2658,3 @@ ProjectManager::~ProjectManager() {
EditorSettings::destroy();
}
}
-
-void ProjectListFilter::_setup_filters(Vector<String> options) {
- filter_option->clear();
- for (int i = 0; i < options.size(); i++) {
- filter_option->add_item(options[i]);
- }
-}
-
-void ProjectListFilter::_search_text_changed(const String &p_newtext) {
- emit_signal("filter_changed");
-}
-
-String ProjectListFilter::get_search_term() {
- return search_box->get_text().strip_edges();
-}
-
-ProjectListFilter::FilterOption ProjectListFilter::get_filter_option() {
- return _current_filter;
-}
-
-void ProjectListFilter::set_filter_option(FilterOption option) {
- filter_option->select((int)option);
- _filter_option_selected(0);
-}
-
-void ProjectListFilter::_filter_option_selected(int p_idx) {
- FilterOption selected = (FilterOption)(filter_option->get_selected());
- if (_current_filter != selected) {
- _current_filter = selected;
- if (is_inside_tree()) {
- emit_signal("filter_changed");
- }
- }
-}
-
-void ProjectListFilter::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE && has_search_box) {
- search_box->set_right_icon(get_theme_icon("Search", "EditorIcons"));
- search_box->set_clear_button_enabled(true);
- }
-}
-
-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", callable_mp(this, &ProjectListFilter::_filter_option_selected));
- add_child(filter_option);
-}
-
-void ProjectListFilter::add_search_box() {
- search_box = memnew(LineEdit);
- search_box->set_placeholder(TTR("Search"));
- search_box->set_tooltip(
- TTR("The search box filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character."));
- search_box->connect("text_changed", callable_mp(this, &ProjectListFilter::_search_text_changed));
- search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- add_child(search_box);
-
- has_search_box = true;
-}
-
-void ProjectListFilter::set_filter_size(int h_size) {
- filter_option->set_custom_minimum_size(Size2(h_size * EDSCALE, 10 * EDSCALE));
-}
-
-ProjectListFilter::ProjectListFilter() {
- _current_filter = FILTER_NAME;
- has_search_box = false;
-}
-
-void ProjectListFilter::clear() {
- if (has_search_box) {
- search_box->clear();
- }
-}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 66b38d0746..407dba0c94 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -39,22 +39,31 @@
class ProjectDialog;
class ProjectList;
-class ProjectListFilter;
+
+enum FilterOption {
+ NAME,
+ PATH,
+ EDIT_DATE,
+};
class ProjectManager : public Control {
GDCLASS(ProjectManager, Control);
- Button *erase_btn;
- Button *erase_missing_btn;
+ TabContainer *tabs;
+
+ ProjectList *_project_list;
+
+ LineEdit *search_box;
+ OptionButton *filter_option;
+
+ Button *run_btn;
Button *open_btn;
Button *rename_btn;
- Button *run_btn;
+ Button *erase_btn;
+ Button *erase_missing_btn;
EditorAssetLibrary *asset_library;
- ProjectListFilter *project_filter;
- ProjectListFilter *project_order_filter;
-
FileDialog *scan_dir;
ConfirmationDialog *language_restart_ask;
ConfirmationDialog *erase_ask;
@@ -64,18 +73,12 @@ class ProjectManager : public Control {
ConfirmationDialog *multi_scan_ask;
ConfirmationDialog *ask_update_settings;
ConfirmationDialog *open_templates;
+
AcceptDialog *run_error_diag;
AcceptDialog *dialog_error;
ProjectDialog *npdialog;
- HBoxContainer *projects_hb;
- TabContainer *tabs;
- ProjectList *_project_list;
-
OptionButton *language_btn;
- Control *gui_base;
-
- bool importing;
void _open_asset_library();
void _scan_projects();
@@ -94,14 +97,13 @@ class ProjectManager : public Control {
void _language_selected(int p_id);
void _restart_confirm();
void _exit_dialog();
- void _scan_begin(const String &p_base);
-
void _confirm_update_settings();
void _load_recent_projects();
void _on_project_created(const String &dir);
void _on_projects_updated();
- void _update_scroll_position(const String &dir);
+ void _scan_multiple_folders(PackedStringArray p_files);
+ void _scan_begin(const String &p_base);
void _scan_dir(const String &path, List<String> *r_projects);
void _install_project(const String &p_zip_path, const String &p_title);
@@ -109,10 +111,9 @@ class ProjectManager : public Control {
void _dim_window();
void _unhandled_input(const Ref<InputEvent> &p_ev);
void _files_dropped(PackedStringArray p_files, int p_screen);
- void _scan_multiple_folders(PackedStringArray p_files);
- void _on_order_option_changed();
- void _on_filter_option_changed();
+ void _on_order_option_changed(int p_idx);
+ void _on_search_term_changed(const String &p_term);
protected:
void _notification(int p_what);
@@ -123,41 +124,4 @@ public:
~ProjectManager();
};
-class ProjectListFilter : public HBoxContainer {
- GDCLASS(ProjectListFilter, HBoxContainer);
-
-public:
- enum FilterOption {
- FILTER_NAME,
- FILTER_PATH,
- FILTER_EDIT_DATE,
- };
-
-private:
- friend class ProjectManager;
-
- OptionButton *filter_option;
- LineEdit *search_box;
- bool has_search_box;
- FilterOption _current_filter;
-
- void _search_text_changed(const String &p_newtext);
- void _filter_option_selected(int p_idx);
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
-
-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();
- FilterOption get_filter_option();
- void set_filter_option(FilterOption);
- ProjectListFilter();
- void clear();
-};
-
#endif // PROJECT_MANAGER_H
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 82ac225ddb..b6621d0d1e 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -333,6 +333,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
header->add_child(search_bar);
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Search"));
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
search_bar->add_child(search_box);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index ce869feddd..d9c95b1944 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -1115,7 +1115,7 @@ void SceneTreeDock::_notification(int p_what) {
beginner_node_shortcuts->set_name("BeginnerNodeShortcuts");
node_shortcuts->add_child(beginner_node_shortcuts);
- Button *button_2d = memnew(Button);
+ button_2d = memnew(Button);
beginner_node_shortcuts->add_child(button_2d);
button_2d->set_text(TTR("2D Scene"));
button_2d->set_icon(get_theme_icon("Node2D", "EditorIcons"));
@@ -1127,7 +1127,7 @@ void SceneTreeDock::_notification(int p_what) {
button_3d->set_icon(get_theme_icon("Node3D", "EditorIcons"));
button_3d->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CREATE_3D_SCENE, false));
- Button *button_ui = memnew(Button);
+ button_ui = memnew(Button);
beginner_node_shortcuts->add_child(button_ui);
button_ui->set_text(TTR("User Interface"));
button_ui->set_icon(get_theme_icon("Control", "EditorIcons"));
@@ -1137,7 +1137,7 @@ void SceneTreeDock::_notification(int p_what) {
favorite_node_shortcuts->set_name("FavoriteNodeShortcuts");
node_shortcuts->add_child(favorite_node_shortcuts);
- Button *button_custom = memnew(Button);
+ button_custom = memnew(Button);
node_shortcuts->add_child(button_custom);
button_custom->set_text(TTR("Other Node"));
button_custom->set_icon(get_theme_icon("Add", "EditorIcons"));
@@ -1160,6 +1160,10 @@ void SceneTreeDock::_notification(int p_what) {
button_instance->set_icon(get_theme_icon("Instance", "EditorIcons"));
button_create_script->set_icon(get_theme_icon("ScriptCreate", "EditorIcons"));
button_detach_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons"));
+ button_2d->set_icon(get_theme_icon("Node2D", "EditorIcons"));
+ button_3d->set_icon(get_theme_icon("Node3D", "EditorIcons"));
+ button_ui->set_icon(get_theme_icon("Control", "EditorIcons"));
+ button_custom->set_icon(get_theme_icon("Add", "EditorIcons"));
filter->set_right_icon(get_theme_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 150c1976ef..c2c877bf68 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -110,7 +110,10 @@ class SceneTreeDock : public VBoxContainer {
Button *button_create_script;
Button *button_detach_script;
+ Button *button_2d;
Button *button_3d;
+ Button *button_ui;
+ Button *button_custom;
HBoxContainer *button_hb;
Button *edit_local, *edit_remote;
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index a62448169d..5a504da397 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -777,6 +777,9 @@ void SceneTreeEditor::_renamed() {
return;
}
+ // Trim leading/trailing whitespace to prevent node names from containing accidental whitespace, which would make it more difficult to get the node via `get_node()`.
+ new_name = new_name.strip_edges();
+
if (!undo_redo) {
n->set_name(new_name);
which->set_metadata(0, n->get_path());
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 628475bbc0..90efb11b7d 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -722,6 +722,15 @@ void ScriptCreateDialog::_update_dialog() {
}
get_ok()->set_disabled(!script_ok);
+
+ Callable entered_call = callable_mp(this, &ScriptCreateDialog::_path_entered);
+ if (script_ok) {
+ if (!file_path->is_connected("text_entered", entered_call)) {
+ file_path->connect("text_entered", entered_call);
+ }
+ } else if (file_path->is_connected("text_entered", entered_call)) {
+ file_path->disconnect("text_entered", entered_call);
+ }
}
void ScriptCreateDialog::_bind_methods() {
@@ -849,7 +858,6 @@ ScriptCreateDialog::ScriptCreateDialog() {
hb->connect("sort_children", callable_mp(this, &ScriptCreateDialog::_path_hbox_sorted));
file_path = memnew(LineEdit);
file_path->connect("text_changed", callable_mp(this, &ScriptCreateDialog::_path_changed));
- file_path->connect("text_entered", callable_mp(this, &ScriptCreateDialog::_path_entered));
file_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hb->add_child(file_path);
path_button = memnew(Button);
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 9f286bd8f6..5da682a148 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -202,7 +202,7 @@ void EditorSettingsDialog::_update_shortcuts() {
Map<String, TreeItem *> sections;
for (List<String>::Element *E = slist.front(); E; E = E->next()) {
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
if (!sc->has_meta("original")) {
continue;
}
@@ -268,7 +268,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
ERR_FAIL_COND(!ti);
String item = ti->get_metadata(0);
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(item);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item);
if (p_idx == 0) {
press_a_key_label->set_text(TTR("Press a Key..."));
@@ -335,7 +335,7 @@ void EditorSettingsDialog::_press_a_key_confirm() {
ie->set_alt(last_wait_for_key->get_alt());
ie->set_metakey(last_wait_for_key->get_metakey());
- Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_configured + "'");
undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie);
@@ -405,6 +405,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
tab_general->add_child(hbc);
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Search"));
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbc->add_child(search_box);
@@ -449,6 +450,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
tab_shortcuts->add_child(hbc);
shortcut_search_box = memnew(LineEdit);
+ shortcut_search_box->set_placeholder(TTR("Search"));
shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hbc->add_child(shortcut_search_box);
shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts));
diff --git a/editor/translations/af.po b/editor/translations/af.po
index 90dca850de..19a9e724ba 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -545,6 +545,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -732,7 +733,7 @@ msgstr "Pas Letterkas"
msgid "Whole Words"
msgstr "Hele Woorde"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Vervang"
@@ -936,6 +937,11 @@ msgid "Signals"
msgstr "Seine"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Eienskappe"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -977,7 +983,7 @@ msgid "Recent:"
msgstr "Onlangse:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Soek:"
@@ -1164,6 +1170,9 @@ msgstr "Projek Stigters"
msgid "Lead Developer"
msgstr "Hoof Ontwikkelaar"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
#, fuzzy
msgid "Project Manager "
@@ -1186,6 +1195,16 @@ msgid "Gold Sponsors"
msgstr "Goue Borge"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Silver Skenkers"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Brons Skenkers"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Borge"
@@ -1674,16 +1693,17 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr ""
-
-#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Node Dock"
msgstr "Nodus Naam:"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Deursoek Klasse"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1969,7 +1989,7 @@ msgstr "Gidse & Lêers:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Voorskou:"
@@ -2829,22 +2849,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2853,8 +2877,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2863,32 +2887,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2950,7 +2974,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Soek"
@@ -3355,7 +3379,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5174,7 +5199,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7850,7 +7875,7 @@ msgid "New Animation"
msgstr "Optimaliseer Animasie"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9903,6 +9928,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projek Bestuurder"
@@ -10340,11 +10366,16 @@ msgid "Batch Rename"
msgstr "Pas Letterkas"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Vervang"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10392,7 +10423,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10452,7 +10483,7 @@ msgid "Reset"
msgstr "Herset Zoem"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12451,6 +12482,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 075bc25f6e..6335b82b15 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -44,12 +44,13 @@
# أحمد مصطفى الطبراني <eltabaraniahmed@gmail.com>, 2020.
# ChemicalInk <aladdinalkhafaji@gmail.com>, 2020.
# Musab Alasaifer <mousablasefer@gmail.com>, 2020.
+# Yassine Oudjana <y.oudjana@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
-"Last-Translator: Musab Alasaifer <mousablasefer@gmail.com>\n"
+"PO-Revision-Date: 2020-09-12 00:46+0000\n"
+"Last-Translator: Yassine Oudjana <y.oudjana@protonmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -58,12 +59,12 @@ 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 4.2-dev\n"
+"X-Generator: Weblate 4.3-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 "معامل type خاطئ لدالة Convert, استخدم احدى الثوابت من مجموعة TYPE_*."
+msgstr "معامل خاطئ لدالة ()Convert, استخدم احدى الثوابت من مجموعة TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -157,11 +158,11 @@ msgstr "أدخل المفتاح هنا"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr "استنساخ المفاتيح المحدد(ة)"
+msgstr "تكرار المفتاح(المفاتيح) المحدد(ة)"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr "إمسح المفاتيح المحدد(ة)"
+msgstr "إمسح المفتاح(المفاتيح) المحدد(ة)"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
@@ -185,7 +186,7 @@ msgstr "تغيير وقت الإطار الرئيسي للحركة"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transition"
-msgstr "تغيير إنتقالية التحريك"
+msgstr "تغيير إنتقالية الرسوم المتحركة"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
@@ -254,11 +255,11 @@ msgstr "شريط ضبط الحركة"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "مدة الحركة (frames)"
+msgstr "مدة الحركة (بالإطارات)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr "مدة الحركة (seconds)"
+msgstr "مدة الحركة (بالثواني)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
@@ -381,7 +382,7 @@ msgstr "حذف مسار التحريك"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr "أنشئ مسار جديد لـ %s و أدخل مفتاح؟"
+msgstr "أنشئ مسار جديد لـ %s و إدخال مفتاح؟"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
@@ -445,11 +446,11 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr "مسارات الحركة يمكنها فقط أن تشير إلى عقد مشغّل الحركة."
+msgstr "مسارات الحركة يمكنها فقط أن تشير إلى عُقد مشغّل الحركة."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
-msgstr "مشغل الحركة لا يمكنه تحريك نفسه, فقط الاعبين الأخرين."
+msgstr "مشغل الحركة لا يمكنه أن يحرك نفسه, فقط الاعبين الأخرين."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
@@ -457,11 +458,11 @@ msgstr "لا يمكن إضافة مقطع جديد بدون جذر"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr "مقطع غير متوافق مع منحنى بيزير Bezier (خصائص فرعية غير متوافقة)"
+msgstr "مقطع غير متوافق مع منحنى بيزر (Bezier) (خصائص فرعية غير متوافقة)"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
-msgstr "إضافة مسار لمنحنى بريزير"
+msgstr "إضافة مسار لمنحنى بيزر"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
@@ -469,7 +470,7 @@ msgstr "مسار المقطع غير صالح, إذن لا يمكن إضافة
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
-msgstr "المقطع ليس من نوع مكاني (Spatial), لا يمكن إضافة مفتاح."
+msgstr "المقطع ليس من نوع مكاني (Spatial), لا يمكن إضافة مفتاح"
#: editor/animation_track_editor.cpp
msgid "Add Transform Track Key"
@@ -497,7 +498,7 @@ msgstr "مفتاح حركة التحريك"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
-msgstr "ذاكرة التخزين المؤقت (Clipboard) فارغة"
+msgstr "الحافظة (Clipboard) فارغة"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
@@ -510,7 +511,7 @@ msgstr "مفتاح تكبير حركة"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
-msgstr "هذا الخيار لا يعمل لتعديل خط (Bezier), لأنه فقط مقطع واحد."
+msgstr "هذا الخيار لا يعمل لتعديل منحنى بيزر (Bezier), لأنه فقط مقطع واحد."
#: editor/animation_track_editor.cpp
msgid ""
@@ -524,12 +525,14 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
-"هذا الانيميشن ينتمي الى مشهد مستورد، لذا فإن أي تغييرات في المسارات "
-"المستوردة لن يتم حفظها.\n"
+"هذه الحركة (رسوم متحركة) تنتمي الى مشهد مستورد، لذا فإن أي تغييرات في "
+"المسارات المستوردة لن يتم حفظها.\n"
"\n"
"لتشغيل الامكانية لإضافة مسارات خاصة، انتقل إلى إعدادات استيراد المشهد واضبط "
-"\"Animation > Storage\" إلى \"Files\"، شغل \"Animation > Keep Custom Tracks"
-"\"، ثم ..."
+"\"رسوم متحركة > تخزين\" إلى \"ملفات\"،\n"
+"شغل \"رسوم متحركة > أحتفظ بالمقاطع (المسارات) المخصصة\"، ثم اعد الاستيراد.\n"
+"يمكنك ايضاً استخدام إعدادات استيراد مسبقة تقوم باستيراد الرسم المتحرك الى "
+"ملفات متفرقة."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
@@ -560,6 +563,7 @@ msgid "Seconds"
msgstr "ثواني"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "إطار خلال ثانية"
@@ -595,7 +599,7 @@ msgstr "تكرير المحدد"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "نسخ محمّل"
+msgstr "نقل مكرر"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -623,7 +627,7 @@ msgstr "إختار العقدة التي سوف يتم تحريكها:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr "إستعمل منحنيات بيزية"
+msgstr "إستعمل منحنيات بيزر"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -738,7 +742,7 @@ msgstr "قضية تشابه"
msgid "Whole Words"
msgstr "كل الكلمات"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "إستبدال"
@@ -796,7 +800,7 @@ msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"لم يتم العثور على الدالة المستهدفة. حدّد دالة سليمة أو أرفق كود للعقدة "
+"لم يتم العثور على الدالة المستهدفة. حدّد دالة سليمة أو أرفق نص برمجي للعقدة "
"المستهدفة."
#: editor/connections_dialog.cpp
@@ -922,15 +926,20 @@ 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 "الإشارات"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "تنقية البلاطات"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
-msgstr "هل أنت(ي) متأكد(ة) أنك تود إزالة كل الإتصالات من هذه الإشارة؟"
+msgstr "هل أنت متأكد أنك تود إزالة كل الإتصالات من هذه الإشارة؟"
#: editor/connections_dialog.cpp
msgid "Disconnect All"
@@ -966,7 +975,7 @@ msgid "Recent:"
msgstr "الحالي:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "بحث:"
@@ -991,7 +1000,7 @@ msgstr "البحث عن بديل لـ:"
#: editor/dependency_editor.cpp
msgid "Dependencies For:"
-msgstr "تابعة لـ:"
+msgstr "تبعيات لـ:"
#: editor/dependency_editor.cpp
msgid ""
@@ -1096,7 +1105,7 @@ msgstr "اخطاء في التحميل!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "إمسح نهائيا %d عنصر(عناصر)؟ (بلا رجعة!)"
+msgstr "هل تريد حذف %d عنصر (عناصر) نهائيًا؟ (لا تراجع!)"
#: editor/dependency_editor.cpp
msgid "Show Dependencies"
@@ -1132,11 +1141,11 @@ msgstr "تغيير قيمة في القاموس"
#: editor/editor_about.cpp
msgid "Thanks from the Godot community!"
-msgstr "شكراً من مجتمع Godot!"
+msgstr "شكراً من مجتمع غودوت!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr "المسهامين في محرك Godot"
+msgstr "المسهامين في محرك غودوت"
#: editor/editor_about.cpp
msgid "Project Founders"
@@ -1146,6 +1155,9 @@ msgstr "مؤسسون المشروع"
msgid "Lead Developer"
msgstr "قائد المطوريين"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "مدير المشروع "
@@ -1167,6 +1179,14 @@ msgid "Gold Sponsors"
msgstr "الرعاة الذهبيين"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "المانحين الفضيين"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "المانحين البرنزيين"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "الرعاة الصغار"
@@ -1201,9 +1221,9 @@ msgid ""
"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
-"محرك \"Godot\" يعتمد على عدد من المكتبات و المكونات البرمجية لملاك اخرين و "
-"لكنها مجانية و مفتوحة المصدر، و كلها متفقة مع شروط الاستخدام لرخصة \"MIT\". "
-"في ما يلي قائمة تحوي جميع هذه المكونات اضافة الى حقوق النشر و شروط الاستخدام "
+"محرك غودوت يعتمد على عدد من المكتبات و المكونات البرمجية لملاك اخرين و لكنها "
+"مجانية و مفتوحة المصدر، و كلها متفقة مع شروط الاستخدام لرخصة \"MIT\". في ما "
+"يلي قائمة تحوي جميع هذه المكونات اضافة الى حقوق النشر و شروط الاستخدام "
"الخاصة بها."
#: editor/editor_about.cpp
@@ -1224,7 +1244,7 @@ msgstr "حدث خطأ عندفتح ملف الحزمة بسبب أن الملف
#: editor/editor_asset_installer.cpp
msgid "%s (Already Exists)"
-msgstr "%s (موجود أصلاً!)"
+msgstr "%s (موجود بالفعل!)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
@@ -1269,39 +1289,39 @@ msgstr "أضف تأثير"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
-msgstr "إعادة تسمية بيوس الصوت"
+msgstr "إعادة تسمية مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Change Audio Bus Volume"
-msgstr "تغيير حجم صوت البيوس"
+msgstr "تغيير حجم صوت مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr "تبديل بيوس الصوت إلي فردي"
+msgstr "تبديل مسار الصوت إلي فردي"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr "تبديل بيوس الصوت إلي صامت"
+msgstr "تبديل مسار الصوت إلي صامت"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr "تبديل بيوس الصوت إلي موثرات التبديل"
+msgstr "تبديل مسار الصوت إلي موثرات التبديل"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr "حدد بيوس الصوت للإرسال"
+msgstr "حدد مسار الصوت للإرسال"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr "أضف موثرات إلي بيوس الصوت"
+msgstr "أضف موثرات إلي مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr "حرك مؤثر البيوس"
+msgstr "حرك ثأثير مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr "مسح تأثير البيوس"
+msgstr "مسح تأثير مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
@@ -1321,7 +1341,7 @@ msgstr "تخطي"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
-msgstr "إعدادات البيوس"
+msgstr "إعدادات مسار الصوت"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -1342,31 +1362,31 @@ msgstr "الصوت"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr "أضف بيوس الصوت"
+msgstr "أضف مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "البيوس الأساسي لا يمكن مسحة!"
+msgstr "مسار الصوت الأساسي لا يمكن مسحة!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr "إمسح بيوس الصوت"
+msgstr "إمسح مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr "تكرير بيوس الصوت"
+msgstr "تكرار مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr "إرجاع صوت البيس"
+msgstr "إرجاع صوت المسار"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr "تحريك بيوس الصوت"
+msgstr "تحريك مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr "إحفظ نسق بيوس الصوت كـ..."
+msgstr "حفظ تخطيط مسار الصوت كـ…"
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -1374,7 +1394,7 @@ msgstr "المكان للنسق الجديد..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr "إفتح نسق بيوس الصوت"
+msgstr "إفتح نسق مسار الصوت"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
@@ -1386,15 +1406,15 @@ msgstr "المخطط"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr "ملف خطأ، ليس ملف نسق بيوس الصوت."
+msgstr "ملف خطأ، ليس ملف نسق مسار الصوت."
#: editor/editor_audio_buses.cpp
msgid "Error saving file: %s"
-msgstr "خطأ !خطأ في تسجيل الملف: s%"
+msgstr "خطأ في تحميل الملف: s%"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr "أضف بيوس"
+msgstr "أضف مسار"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
@@ -1408,7 +1428,7 @@ msgstr "تحميل"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr "تحميل نسق بيوس موجود مسبقاً."
+msgstr "تحميل نسق مسار موجود مسبقاً."
#: editor/editor_audio_buses.cpp
msgid "Save As"
@@ -1416,7 +1436,7 @@ msgstr "حفظ بأسم"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr "إحفظ نسق البيوس هذا إلي ملف."
+msgstr "إحفظ نسق هذا مسار إلي ملف."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -1424,11 +1444,11 @@ msgstr "تحميل الإفتراضي"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr "تحميل نسق البيوس الإفتراضي."
+msgstr "تحميل نسق المسار الإفتراضي."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr "أنشئ نسق بيوس جديد."
+msgstr "أنشئ نسق مسار جديد."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -1476,7 +1496,7 @@ msgstr "ازالة التحميل التلقائي"
#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
-msgstr "تمكين"
+msgstr "تفعيل"
#: editor/editor_autoload_settings.cpp
msgid "Rearrange Autoloads"
@@ -1484,7 +1504,7 @@ msgstr "اعادة ترتيب التحميلات التلقائية"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr "لا يمكن اضافة التحميل التلقائي"
+msgstr "لا يمكن إضافة التحميل التلقائي:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1642,16 +1662,17 @@ 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 "رصيف نظام الملفات و الاستيراد"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "نظام الملفات"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "رصيف الاستيراد"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1679,7 +1700,7 @@ msgstr "(المُحرر مُعطّل)"
#: editor/editor_feature_profile.cpp
msgid "Class Options:"
-msgstr "إعدادات الصف Class:"
+msgstr "إعدادات الصف (Class):"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
@@ -1748,7 +1769,7 @@ msgstr "إعدادات الصف Class"
#: editor/editor_feature_profile.cpp
msgid "New profile name:"
-msgstr "اسم مَلف profile جديد:"
+msgstr "اسم مَلف (profile) جديد:"
#: editor/editor_feature_profile.cpp
msgid "Erase Profile"
@@ -1913,7 +1934,7 @@ msgstr "الوجهات والملفات:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "إستعراض:"
@@ -1978,11 +1999,11 @@ msgstr "الافتراضي:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr "قائمة الطرق"
+msgstr "الطُرق"
#: editor/editor_help.cpp
msgid "Theme Properties"
-msgstr "خصائص الثمة"
+msgstr "خصائص الثِمة"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2010,7 +2031,7 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Method Descriptions"
-msgstr "أوصاف الدوال Method"
+msgstr "أوصاف الدوال"
#: editor/editor_help.cpp
msgid ""
@@ -2087,7 +2108,7 @@ msgstr "خاصية"
#: editor/editor_help_search.cpp
msgid "Theme Property"
-msgstr "خاصية الموضوع Theme"
+msgstr "خاصية الموضوع (Theme)"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
@@ -2232,7 +2253,7 @@ msgstr "حفظ المشهد"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr "يحلل"
+msgstr "جاري التحليل"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
@@ -2240,7 +2261,7 @@ msgstr "ينشئ الصورة المصغرة"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr "هذه العملية لا يمكنها الإكتمال من غير جذر شجرة ."
+msgstr "هذه العملية لا يمكنها الإكتمال من غير شجرة رئيسة."
#: editor/editor_node.cpp
msgid ""
@@ -2386,7 +2407,7 @@ msgstr "يتطلب حفظ المشهد توافر عُقدة رئيسة."
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr "حفظ المشهد كـ..."
+msgstr "حفظ المشهد كـ…"
#: editor/editor_node.cpp
msgid "No"
@@ -2497,31 +2518,33 @@ msgstr "غير قادر علي تفعيل إضافة البرنامج المُس
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
msgstr ""
-"غير قادر علي إيجاد منطقة الكود من أجل إضافة البرنامج في: 'res://addons/%s'."
+"غير قادر علي إيجاد منطقة النص البرمجي من أجل إضافة البرنامج في: 'res://"
+"addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr "غير قادر علي تحميل كود الإضافة من المسار: '%s'."
+msgstr "غير قادر علي تحميل النص البرمجي للإضافة من المسار: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
-"غير قادر علي تحميل كود الإضافة من المسار: '%s' يبدو أن الكود يوجد فيه "
-"أخطاء , الرجاء مراجعة الكود."
+"غير قادر علي تحميل النص البرمجي الإضافب من المسار: '%s' يبدو أن شِفرة "
+"البرمجية يوجد بها أخطاء , الرجاء مراجعة الشِفرة البرمجية."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
-"غير قادر علي تحميل كود الإضافة من المسار: '%s' النوع الأساسي ليس إضافة "
-"المُعدل."
+"غير قادر علي تحميل النص البرمجي الإضافي من المسار: '%s' النوع الأساسي ليس "
+"إضافة المُعدل."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
-"غير قادر علي تحميل كود الإضافة من المسار: '%s' الكود ليس في وضع الأداة."
+"غير قادر علي تحميل النص البرمجي الإضافي من المسار: '%s' النص البرمجي ليس في "
+"وضع الأداة."
#: editor/editor_node.cpp
msgid ""
@@ -2702,15 +2725,15 @@ msgstr "حفظ جميع المشاهد"
#: editor/editor_node.cpp
msgid "Convert To..."
-msgstr "تحويل الي..."
+msgstr "تحويل إلى..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr "مكتبة الميش..."
+msgstr "مكتبة مجسّمات..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr "مجموعة البلاط..."
+msgstr "مجموعة بلاط..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2724,7 +2747,7 @@ msgstr "إعادة تراجع"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
-msgstr "ادوات لكل-المشهد او لمشاريع متنوعه."
+msgstr "أدوات مشروع أو مشهد متنوعة."
#: editor/editor_node.cpp editor/project_manager.cpp
#: editor/script_create_dialog.cpp
@@ -2737,7 +2760,7 @@ msgstr "إعدادات المشروع..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
-msgstr "التحكم في الإصدار"
+msgstr "التحكم بالإصدار"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
@@ -2761,7 +2784,7 @@ msgstr "فتح مجلد بيانات المشروع"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
-msgstr "ادوات"
+msgstr "أدوات"
#: editor/editor_node.cpp
msgid "Orphan Resource Explorer..."
@@ -2769,7 +2792,7 @@ msgstr "متصفح الموارد أورفان..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr "غادر إلى قائمه المشاريع"
+msgstr "العودة إلى قائمة المشاريع"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2782,63 +2805,72 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"حينما يتم التصدير أو النشر، ملف التشغيل الناتج سوف يحاول الإتصال إلي عنوان "
-"الأي بي الخاص بهذا الكمبيوتر من أجل تصحيح الأخطاء."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "نشر مصغر مع نظام شبكات الملفات"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
-"حينما يتم تفعيل هذا الإعداد، التصدير او النشر سوف ينتج ملف تشغيل بالحد "
-"الأدني.\n"
+"حينما يتم تفعيل هذا الإعداد، التصدير أو النشر سوف ينتج ملف تشغيل بالحد "
+"الأدنى (مبسط).\n"
"نظام الملفات سوف يتم توفيره بواسطة المُعدل من خلال الشبكة.\n"
-"علي الأندرويد، النشر سوف يستخدم وصلة اليو اس بي من أجل أداء أسرع. هذا "
-"الأعداد يسرع الإختبار للإلعاب مع الملفات الكثيرة."
+"على الأندرويد، النشر سوف يستخدم وصلة اليو إس بي من أجل أداء أسرع. هذا "
+"الإعداد يسرّع إختبار الألعاب ذو الحجم الكبير."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
msgstr "أشكال إصطدام ظاهرة"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
-"أشكال الإصطدام و وعقد الراي كاست (من أجل 2D و 3D) سوف تكون ظاهرة في اللعبة "
-"العاملة إذا كان هذا الإعداد مُفعل."
+"أشكال الإصطدام و عُقد الراي كاست (من أجل 2D و 3D) سوف تكون ظاهرة في اللعبة "
+"العاملة إذا كان هذا الإعداد مُفعّل."
#: editor/editor_node.cpp
msgid "Visible Navigation"
msgstr "الإنتقال المرئي"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
-msgstr "ميشات التنقل والبوليجين سوف يكونون ظاهرين حينما يتم تفعيل هذا الإعداد."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
+msgstr ""
+"مجسمات التنقل والأشكال المضلعة سوف تكون ظاهرة حينما يتم تفعيل هذا الإعداد."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "مزامنة تغييرات المشهد"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"حينما يكون هذا الإعداد مُفعل، أي تغيير يحدث في المشهد من خلال المُعدل سوف يتم "
"تطبيقة في اللعبة العاملة.\n"
@@ -2846,32 +2878,34 @@ msgstr ""
"الملفات."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "مزامنة تغييرات الكود"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
-"حينما يكون هذا الإعداد مُفعل، أي كود يتم حفظه سيتم إعادة تشغيلة في اللعبة "
-"العاملة.\n"
-"حينما يتم إستخدامة عن بعد علي جهاز، سيكون هذا أكثر فعالية مع نظام شبكات "
+"حينما يكون هذا الإعداد مُفعل، أي نص برمجي يتم حفظه سيتم إعادة تحميله في "
+"اللعبة العاملة.\n"
+"حينما يتم إستخدامه عن بُعد على جهاز، سيكون هذا أكثر فعالية مع نظام شبكات "
"الملفات."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr "المُعدل"
+msgstr "المحرّر"
#: editor/editor_node.cpp
msgid "Editor Settings..."
-msgstr "إعدادات المحرّر"
+msgstr "إعدادات المحرّر…"
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr "نسق المُعدل"
+msgstr "تنسيق المحرّر"
#: editor/editor_node.cpp
msgid "Take Screenshot"
@@ -2879,11 +2913,11 @@ msgstr "أخذ صورة للشاشة"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "لقطات الشاشة تكون محفوظة في مجلّد البيانات/الإعدادت داخل المحرّر"
+msgstr "لقطات الشاشة تكون محفوظة في مجلّد بيانات/إعدادات المحرّر."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "إلغاء/تفعيل وضع الشاشة الكاملة"
+msgstr "تفعيل/إلغاء وضع الشاشة الكاملة"
#: editor/editor_node.cpp
msgid "Toggle System Console"
@@ -2891,11 +2925,11 @@ 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"
@@ -2903,7 +2937,7 @@ msgstr "فتح مجلّد إعدادات المحرّر"
#: editor/editor_node.cpp
msgid "Manage Editor Features..."
-msgstr "إدارة ميّزات المحرّر"
+msgstr "إدارة ميّزات المحرّر…"
#: editor/editor_node.cpp
msgid "Manage Export Templates..."
@@ -2918,7 +2952,7 @@ msgstr "مساعدة"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "بحث"
@@ -2933,7 +2967,7 @@ msgstr "الأسئلة و الأجوبة"
#: editor/editor_node.cpp
msgid "Report a Bug"
-msgstr "إرسال تقرير عن bug أو خلل في شيء ما"
+msgstr "إرسال تقرير عن خلل برمجي"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
@@ -2945,7 +2979,7 @@ msgstr "المجتمع"
#: editor/editor_node.cpp
msgid "About"
-msgstr "عن"
+msgstr "عن هذا التطبيق"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -2957,11 +2991,11 @@ msgstr "تشغيل"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr "إيقاف جلسة المشهد من أجل تنقيح الكبوات البرمجية debugging."
+msgstr "إيقاف المشهد الحالي من أجل المعالجة البرمجية."
#: editor/editor_node.cpp
msgid "Pause Scene"
-msgstr "إيقاف مؤقت للمشهد"
+msgstr "إيقاف مؤقّت للمشهد"
#: editor/editor_node.cpp
msgid "Stop the scene."
@@ -2969,7 +3003,7 @@ msgstr "إيقاف المشهد."
#: editor/editor_node.cpp
msgid "Play the edited scene."
-msgstr "تشغيل المشهد المُعدل."
+msgstr "تشغيل المشهد المُعدّل."
#: editor/editor_node.cpp
msgid "Play Scene"
@@ -2994,7 +3028,7 @@ msgstr "حفظ و إعادة تشغيل"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr "يدور حينما يتم إعادة رسم نافذة المحرّر"
+msgstr "قم بالتدوير أثناء إعادة رسم نافذة المحرّر."
#: editor/editor_node.cpp
msgid "Update Continuously"
@@ -3014,7 +3048,7 @@ msgstr "نظام الملفات"
#: editor/editor_node.cpp
msgid "Inspector"
-msgstr "مُراقب"
+msgstr "المُراقب"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
@@ -3099,27 +3133,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_node.h
msgid "Warning!"
@@ -3236,7 +3270,7 @@ msgstr "إلحاق..."
#: editor/editor_properties.cpp
msgid "Invalid RID"
-msgstr "إسم RID غير صالح."
+msgstr "RID غير صالح"
#: editor/editor_properties.cpp
msgid ""
@@ -3333,9 +3367,11 @@ msgid "Add Key/Value Pair"
msgstr "إضافة زوج مفتاح/قيمة"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"لا يوجد إعداد تصدير مسبق عامل لهذه المنصة.\n"
"من فضلك أضف إعداد تصدير عامل في قائمة التصدير."
@@ -3584,7 +3620,7 @@ msgstr "حدد ملف القالب"
#: editor/export_template_manager.cpp
msgid "Godot Export Templates"
-msgstr "إدارة قوالب التصدير Godot"
+msgstr "إدارة قوالب التصدير لغودوت"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
@@ -3708,11 +3744,11 @@ msgstr "مشهد جديد..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
-msgstr "فتح السكريبت..."
+msgstr "فتح النص البرمجي..."
#: editor/filesystem_dock.cpp
msgid "New Resource..."
-msgstr "مورد جديد..."
+msgstr "مصدر جديد..."
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
@@ -3733,7 +3769,7 @@ msgstr "إعادة التسمية"
#: editor/filesystem_dock.cpp
msgid "Previous Folder/File"
-msgstr "‪المجلد/الملف السابق"
+msgstr "المجلد/الملف السابق"
#: editor/filesystem_dock.cpp
msgid "Next Folder/File"
@@ -3793,7 +3829,7 @@ msgstr "مجلد:"
#: editor/find_in_files.cpp
msgid "Filters:"
-msgstr "فلتر:"
+msgstr "تنقيات:"
#: editor/find_in_files.cpp
msgid ""
@@ -3822,7 +3858,7 @@ msgstr "إيجاد: "
#: editor/find_in_files.cpp
msgid "Replace: "
-msgstr "إستبدال:"
+msgstr "إستبدال: "
#: editor/find_in_files.cpp
msgid "Replace all (no undo)"
@@ -3895,7 +3931,7 @@ msgstr "إستيراد كمشهد واحد"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Animations"
-msgstr "إستيراد مع إنميشن منفصلة"
+msgstr "إستيراد مع رسوم متحركة منفصلة"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials"
@@ -3911,15 +3947,15 @@ msgstr "إستيراد مع عناصر+موارد منفصلة"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Animations"
-msgstr "إستيراد مع عناصر + إنميشن منفصلة"
+msgstr "إستيراد مع عناصر + رسوم متحركة منفصلة"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials+Animations"
-msgstr "إستيراد مع مصادر+ إنميشن منفصلة"
+msgstr "إستيراد مع مصادر+ رسوم متحركة منفصلة"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials+Animations"
-msgstr "إستيراد مع عناصر + مصادر + إنميشين منفصلين"
+msgstr "إستيراد مع عناصر + مصادر + رسوم متحركة منفصلين"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes"
@@ -3944,23 +3980,23 @@ msgstr "انشاء خارطة الضوء"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr "انشاء من اجل الميش: "
+msgstr "انشاء من اجل المجسم: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr "تشغيل الكود المُخصص..."
+msgstr "تشغيل النص البرمجي المُخصص..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
-msgstr "لا يمكن تحميل الكود المستورد أو المطبوع:"
+msgstr "لا يمكن تحميل النص البرمجي المستورد أو المطبوع:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
-msgstr "كود مستورد-ملصق متضرر/خاطئ (تحقق من وحدة التحكم):"
+msgstr "النص البرمجي مستورد-ملصق متضرر/خاطئ (تحقق من وحدة التحكم):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
-msgstr "خطأ في تشغيل الكود الملصق- المستورد:"
+msgstr "خطأ في تشغيل النص البرمجي الملصق- المستورد:"
#: editor/import/resource_importer_scene.cpp
msgid "Did you return a Node-derived object in the `post_import()` method?"
@@ -3980,15 +4016,15 @@ msgstr "حدد كإفتراضي من أجل '%s'"
#: editor/import_dock.cpp
msgid "Clear Default for '%s'"
-msgstr "إخلاء الإفتراضي لـ '%s'"
+msgstr "إخلاء الإفتراضي ل '%s'"
#: editor/import_dock.cpp
msgid "Import As:"
-msgstr "إستيراد كـ:"
+msgstr "إستيراد ك:"
#: editor/import_dock.cpp
msgid "Preset"
-msgstr "إعداد مُسبق..."
+msgstr "إعداد مُسبق"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4429,38 +4465,38 @@ msgstr "إلغاء/تفعيل التشغيل التلقائي"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
-msgstr "إسم الحركة الجديد:"
+msgstr "إسم رسم المتحرك جديد:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Anim"
-msgstr "حركة جديدة"
+msgstr "رسم متحرك جديدة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
-msgstr "تغيير إسم الحركة:"
+msgstr "تغيير إسم الرسم المتحرك:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
-msgstr "مسح الحركة؟"
+msgstr "مسح الرسم المتحرك؟"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Remove Animation"
-msgstr "مسح الحركة"
+msgstr "مسح الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Invalid animation name!"
-msgstr "خطأ: إسم الرسوم المتحركة خاطئ!"
+msgstr "إسم الرسم المتحرك خاطئ!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation name already exists!"
-msgstr "اسم الحركة موجود بالفعل!"
+msgstr "إسم الرسم المتحرك موجود بالفعل!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Rename Animation"
-msgstr "إعادة تسمية الحركة"
+msgstr "إعادة تسمية الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
@@ -4472,23 +4508,23 @@ msgstr "تغيير وقت الدمج"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Load Animation"
-msgstr "تحميل حركة"
+msgstr "تحميل الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
-msgstr "تكرير الحركة"
+msgstr "تكرار الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to copy!"
-msgstr "لا حركة رسومية لنسخها!"
+msgstr "لا رسم متحرك لنسخها!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation resource on clipboard!"
-msgstr "لا يوجد مورد لرسومية متحركة في الحافظة clipboard!"
+msgstr "لا يوجد مورد لرسم متحرك في الحافظة clipboard!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
-msgstr "الحركة الرسومية المُلصقة"
+msgstr "تم لصق الرسوم المتحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Paste Animation"
@@ -4500,39 +4536,39 @@ msgstr "لا رسومات متحركة لتحريرها!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
-msgstr "تشغيل الحركة المختارة بشكل عكسي من الموقع الحالي. (زر A)"
+msgstr "تشغيل الرسم المتحرك المختار بشكل عكسي من الموقع الحالي. (زر A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr "تشيل الحركة المختارة بشكل عكسي من النهاية. (Shift+ش)"
+msgstr "تشغيل الرسم المتحرك المختار بشكل عكسي من النهاية. (Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
-msgstr "إيقاف تشغيل الحركة. (س)"
+msgstr "إيقاف تشغيل الرسم المتحرك. (S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
-msgstr "تشغيل الحركة المحددة من البداية. (Shift+ي)"
+msgstr "تشغيل الرسم المتحرك المحدد من البداية. (Shift+D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from current pos. (D)"
-msgstr "تشغيل الحركة المختارة من الموقع الحالي. (زر D)"
+msgstr "تشغيل الرسم المتحرك المختار من الموقع الحالي. (D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation position (in seconds)."
-msgstr "موقع الحركة (بالثواني)."
+msgstr "موقع الرسم المتحرك (بالثواني)."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Scale animation playback globally for the node."
-msgstr "تكبير تشغيل الحركة عالمياً من العقدة."
+msgstr "تكبير تشغيل الرسم المتحرك عالمياً من العقدة."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
-msgstr "أدوات الحركة"
+msgstr "أدوات الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr "صورة متحركة"
+msgstr "الرسم المتحرك"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Edit Transitions..."
@@ -4604,11 +4640,11 @@ msgstr "تثبيت مُشغّل الرسوميات المتحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
-msgstr "إنشاء حركة جديدة"
+msgstr "إنشاء رسوم متحركة جديدة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
-msgstr "إسم الحركة:"
+msgstr "إسم الرسم المتحرك:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
@@ -4858,7 +4894,7 @@ msgstr "عقدة التنقل"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Import Animations..."
-msgstr "إستيراد الحركة..."
+msgstr "إستيراد الرسوم المتحركة..."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Edit Node Filters"
@@ -4922,7 +4958,7 @@ msgstr "فشل الطلب ، انتهت المهلة"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Timeout."
-msgstr "إنتهى الوقت"
+msgstr "انتهت المهلة."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
@@ -4962,7 +4998,7 @@ msgstr "خطأ في إنشاء الطلب"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Idle"
-msgstr "عاطل"
+msgstr "الخمول (idle)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install..."
@@ -5096,7 +5132,7 @@ msgid "Bake Lightmaps"
msgstr "إعداد خرائط الضوء"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "استعراض"
@@ -7320,7 +7356,6 @@ msgid "Audio Listener"
msgstr "المستمع الصوتي"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Enable Doppler"
msgstr "تفعيل دوبلر"
@@ -7548,7 +7583,6 @@ msgid "View Z-Near:"
msgstr "إظهار Z-Near:"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "View Z-Far:"
msgstr "إظهار Z-Far:"
@@ -7655,9 +7689,8 @@ msgid "Invalid geometry, can't create light occluder."
msgstr "هندسياً غير صالح، لا يمكن إنشاء حِظار (occluder) الضوء."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create LightOccluder2D Sibling"
-msgstr "أنشئ شكل مُطبق"
+msgstr "أنشاء ضوء محجوب ثنائي الأبعاد"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
@@ -7736,7 +7769,8 @@ msgid "New Animation"
msgstr "رسومية متحركة جديدة"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "السرعة (إطار ف. ث. FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -7918,7 +7952,7 @@ msgstr "عنصر مُفعل اختياري"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Named Sep."
-msgstr "الفاصل المُسمّى"
+msgstr "الفاصل المُسمّى."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
@@ -7998,9 +8032,8 @@ msgid "Erase Selection"
msgstr "إزالة عملية الاختيار"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Fix Invalid Tiles"
-msgstr "اسم غير صالح."
+msgstr "أصلح البلاطة غير الصالحة"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -8028,9 +8061,8 @@ msgid "Erase TileMap"
msgstr "مسح خريطة البلاط TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "جد"
+msgstr "جد البلاطة"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
@@ -8045,9 +8077,8 @@ msgid "Enable Priority"
msgstr "تمكين الأولوية"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter tiles"
-msgstr "فلتر الملفات..."
+msgstr "تنقية البلاطات"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
@@ -8095,9 +8126,8 @@ msgid "Add Texture(s) to TileSet."
msgstr "إضافة نقش(نقوش) إلى مُحدد البلاط TileSet."
#: 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"
@@ -8112,9 +8142,8 @@ msgid "New Single Tile"
msgstr "بلاطة مُفردة جديدة"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Autotile"
-msgstr "إظهار الملفات"
+msgstr "بلاط-تلقائي جديد"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Atlas"
@@ -8150,23 +8179,23 @@ msgstr "الإطباق Occlusion"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Navigation"
-msgstr "التصفح"
+msgstr "التنقل"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Bitmask"
-msgstr "قناع البِت Bitmask"
+msgstr "قناع البِت"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Priority"
-msgstr "التفاضل Priority"
+msgstr "الأولية"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Z Index"
-msgstr "تراتبية المحور Z"
+msgstr "ترتيبية المحور Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Region Mode"
-msgstr "وضع الأقليم Region"
+msgstr "وضع الأقليم"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision Mode"
@@ -8174,19 +8203,19 @@ msgstr "وضع التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Occlusion Mode"
-msgstr "وضع الإطباق Occlusion"
+msgstr "وضع الإطباق"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Navigation Mode"
-msgstr "وضع التصفح"
+msgstr "وضع التنقل"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Bitmask Mode"
-msgstr "وضع Bitmask"
+msgstr "وضع قناع-البِت"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Priority Mode"
-msgstr "وضع التفاضل Priority"
+msgstr "وضع الأولية"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon Mode"
@@ -8194,21 +8223,19 @@ msgstr "وضع الأيقونة"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Z Index Mode"
-msgstr "وضع Z Index"
+msgstr "وضع ترتيبية المحور Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
-msgstr "نسخ bitmask."
+msgstr "نسخ قناع-البِت."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste bitmask."
-msgstr "لصق الحركة"
+msgstr "لصق قناع-البِت"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Erase bitmask."
-msgstr "زر الفأرة الأيمن: مسح النقطة."
+msgstr "مسح قناع-البِت."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new rectangle."
@@ -8497,7 +8524,7 @@ msgstr "الحالة"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "View file diffs before committing them to the latest version"
-msgstr "إظهار آخر تعديلات الملف قبل قبولهم في آخر نسخة."
+msgstr "إظهار آخر تعديلات الملف قبل قبولهم في آخر نسخة"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No file diff is active"
@@ -8846,11 +8873,11 @@ msgstr "ثابت جذر-العدد2 (1.414214)، أي قيمة جذر العدد
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr "يحسب القيمة المطلقة لقيمة المَعلم."
+msgstr "يُرجع القيمة المطلقة لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr "يُرجع قيمة جيب التمام \"arc-cosine\" للمَعلم."
+msgstr "يُرجع قيمة جيب التمام للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic cosine of the parameter."
@@ -8866,11 +8893,11 @@ msgstr "يُرجع قيمة جيب القطع الزائد العكسي للمَ
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr "يُرجع قيمة ظل الزاوية العكسية \"arc-tangent\" للمَعلم."
+msgstr "يُرجع قيمة ظل الزاوية العكسية للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr "يُرجع قيمة ظل الزاوية العكسي \"arc-tangent\" للمعالم."
+msgstr "يُرجع قيمة ظل الزاوية العكسي للمَعالم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic tangent of the parameter."
@@ -8900,11 +8927,11 @@ msgstr "يحوّل قيمة (كمية) من الراديان إلى الدرجا
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr "الدالة Base-e."
+msgstr "الدالة الأسية Base-e."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr "الدالة Base-2."
+msgstr "الدالة الأسية Base-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
@@ -8953,7 +8980,7 @@ 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"
@@ -8977,11 +9004,11 @@ msgstr "يستخرج إشارة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr "يُرجع جيب sine المَعلم parameter."
+msgstr "يُرجع جيب المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic sine of the parameter."
-msgstr "يُرجع قيمة الجيب العكس hyperbolic sine للمَعلم."
+msgstr "يُرجع قيمة الجيب العكس للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
@@ -9014,15 +9041,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr "يُرجع قيمة ظل الزاوية tangent للمَعلم."
+msgstr "يُرجع قيمة ظل الزاوية للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic tangent of the parameter."
-msgstr "يُرجع قيمة ظل الزاوية العكسي hyperbolic tangent للمَعلم."
+msgstr "يُرجع قيمة ظل الزاوية العكسي للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the truncated value of the parameter."
-msgstr "يجد قيمة الاقتطاع truncated للمَعلم."
+msgstr "يجد قيمة الاقتطاع للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -9061,7 +9088,6 @@ msgid "Perform the texture lookup."
msgstr "إجراء البحث عن النقش."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Cubic texture uniform lookup."
msgstr "البحث عن النقش المكعبي الموحد."
@@ -9150,7 +9176,7 @@ 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."
@@ -9273,7 +9299,7 @@ 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."
@@ -9866,6 +9892,7 @@ msgstr ""
"هل أنت متأكد من فحص %s من المجلدات بحثاً عن مشاريع غودوت متوافرة؟\n"
"قد يستغرق وقتاً."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "مدير المشروع"
@@ -9945,7 +9972,7 @@ msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
msgstr ""
-"اسم فعالية غير صحيح. لا يمكن أن يكون فارغاً أو يتضمن '/'، ':'، '='، '\\' أو "
+"اسم فعالية غير صحيح. لا يمكن أن يكون فارغاً أو يتضمن '/'، ':'، '='، '\\' أو "
"'\"'"
#: editor/project_settings_editor.cpp
@@ -10305,11 +10332,18 @@ msgid "Batch Rename"
msgstr "إعادة تسمية الدفعة"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "إستبدال: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "بادئة"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "لاحقة"
#: editor/rename_dialog.cpp
@@ -10357,7 +10391,8 @@ msgid "Per-level Counter"
msgstr "العداد وفق-المستوى"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "إذا تم تحديده فإن العداد سيعيد البدء لكل مجموعة من العُقد الأبناء"
#: editor/rename_dialog.cpp
@@ -10417,7 +10452,8 @@ msgid "Reset"
msgstr "إعادة تعيين"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "خطأ ذو علاقة بالتعبير الاعتيادي Regular Expression"
#: editor/rename_dialog.cpp
@@ -10530,7 +10566,7 @@ msgstr "حذف العُقدة %d مع جميع أبنائها؟"
#: editor/scene_tree_dock.cpp
msgid "Delete %d nodes?"
-msgstr "حذف العُقد %d"
+msgstr "حذف العُقد %d؟"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10677,9 +10713,8 @@ msgid "Change Type"
msgstr "تغيير النوع"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Reparent to New Node"
-msgstr "إنشاء %s جديد"
+msgstr "تعين لعقدة جديدة"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
@@ -10735,22 +10770,19 @@ msgstr "مسح الموروث؟ (لا تراجع!)"
#: editor/scene_tree_editor.cpp
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 "إضافة إلي مجموعة"
+msgstr "مجموعة الأزرار"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "خطأ في الإتصال"
+msgstr "(الإتصال من)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
@@ -10845,23 +10877,20 @@ msgid "Path is not local."
msgstr "المسار ليس محلياً."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid base path."
msgstr "مسار غير صالح."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "ملف أو مجلد مع هذا الأسم موجود بالفعل."
+msgstr "يوجد ملف/مجلد بنفس الاسم."
#: editor/script_create_dialog.cpp
msgid "File does not exist."
msgstr "الملف غير موجود."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "يجب أن يستخدم صيغة صحيحة."
+msgstr "صيغة غير صالحة."
#: editor/script_create_dialog.cpp
msgid "Wrong extension chosen."
@@ -10912,33 +10941,28 @@ msgid "Invalid inherited parent name or path."
msgstr "إن اسم أو مسار الأب (الأصل parent) الموروث غير صالح."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "شجرة الحركة صحيحة."
+msgstr "مسار/اسم البرنامج النصي صالح."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
-msgstr "المسموح: a-z، A-Z ، 0-9 ، _ و ."
+msgstr "المسموح: a-z، A-Z ، 0-9 ، _ و ."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in script (into scene file)."
-msgstr "عمليات مع ملفات المشهد."
+msgstr "نص برمجي مدموج (داخل ملف المشهد)."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "إنشاء ملف كود جديد"
+msgstr "سيتم إنشاء ملف برمجي جديد."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "تحميل نسق بيوس موجود مسبقاً."
+msgstr "سيتم تحميل ملف برمجي موجود مسبقاً."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script file already exists."
-msgstr "التحميل التلقائي '%s' موجود اصلا!"
+msgstr "الملف البرمجي موجود بالفعل."
#: editor/script_create_dialog.cpp
msgid ""
@@ -10949,19 +10973,16 @@ msgstr ""
"تعديلها باستخدام مُحرر خارجي."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "إسم صنف"
+msgstr "اسم الفئة:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Template:"
-msgstr "مسح القالب"
+msgstr "القالب:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in Script:"
-msgstr "فتح الكود"
+msgstr "ملف النص المُدمج:"
#: editor/script_create_dialog.cpp
msgid "Attach Node Script"
@@ -10976,39 +10997,32 @@ msgid "Bytes:"
msgstr "Bytes:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Warning:"
-msgstr "تحذيرات"
+msgstr "تحذير:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Error:"
-msgstr "خطأ!"
+msgstr "خطأ:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error"
-msgstr "خطأ في نسخ"
+msgstr "خطأ في C++"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error:"
-msgstr "خطأ في نسخ"
+msgstr "خطأ C++ :"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source"
-msgstr "مورد"
+msgstr "مصدر C++"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source:"
-msgstr "مورد"
+msgstr "مصدر:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source:"
-msgstr "مورد"
+msgstr "مصدر C++:"
#: editor/script_editor_debugger.cpp
msgid "Stack Trace"
@@ -11019,9 +11033,8 @@ msgid "Errors"
msgstr "أخطاء"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Child process connected."
-msgstr "غير متصل"
+msgstr "العملية التابعة متصلة."
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
@@ -11029,12 +11042,11 @@ msgstr "خطأ في نسخ"
#: editor/script_editor_debugger.cpp
msgid "Video RAM"
-msgstr "ذاكرة الفيديو Video RAM"
+msgstr "الذاكرة العشوائية للفيديو"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Skip Breakpoints"
-msgstr "مسح النقاط"
+msgstr "تخطي نقاط التكسّر"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -11081,9 +11093,8 @@ msgid "Total:"
msgstr "المجموع الكلي:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Export list to a CSV file"
-msgstr "تصدير الملف"
+msgstr "تصدير القائمة إلى ملف CSV"
#: editor/script_editor_debugger.cpp
msgid "Resource Path"
@@ -11126,18 +11137,16 @@ msgid "Export measures as CSV"
msgstr "تصدير القياسات ك CSV"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Erase Shortcut"
-msgstr "تخفيف للخارج"
+msgstr "حذف الاختصار"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
msgstr "إعادة تعيين الاختصارات"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Change Shortcut"
-msgstr "تغيير المرتكزات"
+msgstr "تغيير الاختصارات"
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
@@ -11209,19 +11218,16 @@ 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
msgid "Change Torus Outer Radius"
@@ -11265,12 +11271,11 @@ msgstr "مكتبة GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr "تمكين نمط البرمجة Singleton لِ GDNative"
+msgstr "تمكين نمط البرمجة Singleton لـ GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "تعطيل دوار التحديث"
+msgstr "تعطيل نمط البرمجة Singleton لـ GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -11285,17 +11290,16 @@ msgid "GDNative"
msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Step argument is zero!"
-msgstr "الخطوة (المتغيرة المدخلة/argument) تساوي صفر !"
+msgstr "معامل الخطوة تساوي صفر!"
#: 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"
@@ -11303,42 +11307,35 @@ msgstr "لا تستند على ملف مورد"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (missing @path)"
-msgstr ""
-"instance dictionary format نموذج الشكل القاموسي غير صالح - المسار مفقود"
+msgstr "نموذج الشكل القاموسي غير صالح (@المسار مفقود)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (can't load script at @path)"
-msgstr ""
-"instance dictionary format نموذج الشكل القاموسي غير صالح - لا يمكن تحميل "
-"السكريبت من المسار"
+msgstr "نموذج الشكل القاموسي غير صالح (لا يمكن تحميل النص البرمجي من @المسار)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (invalid script at @path)"
-msgstr ""
-"instance dictionary format نموذج الشكل القاموسي غير صالح - السكريبت في "
-"المسار غير صالح"
+msgstr "نموذج الشكل القاموسي غير صالح ( النص البرمجي غير صالح في @المسار)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr "مجسّد القاموس غير صالح (أصناف فرعية غير صالحة)"
+msgstr "نموذج القاموس غير صالح (أصناف فرعية غير صالحة)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
-msgstr "لا يمكن للكائن Object أن يمنح طولاً."
+msgstr "لا يمكن للكائن أن يمنح طولاً."
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Next Plane"
msgstr "التبويب التالي"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Previous Plane"
msgstr "التبويب السابق"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Plane:"
-msgstr "المستوى:"
+msgstr "التبويت:"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Next Floor"
@@ -11357,14 +11354,12 @@ msgid "GridMap Delete Selection"
msgstr "خريطة الشبكة GridMap لحذف المُختار"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Fill Selection"
-msgstr "كُل المُحدد"
+msgstr "تحديد الملئ خريطة-الشبكة"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "كُل المُحدد"
+msgstr "تحديد اللصق خريطة-الشبكة"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -11431,9 +11426,8 @@ msgid "Cursor Clear Rotation"
msgstr "مسح تدوير المؤشر"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Paste Selects"
-msgstr "كُل المُحدد"
+msgstr "تحديد اللصق"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clear Selection"
@@ -11452,9 +11446,8 @@ msgid "Pick Distance:"
msgstr "اختر المسافة:"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter meshes"
-msgstr "وضع المُصفي:"
+msgstr "تنقية المجسمات"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
@@ -11561,7 +11554,7 @@ msgstr "عثر على تسلسل بت ولكن ليس العقدة في المك
#: modules/visual_script/visual_script.cpp
msgid "Stack overflow with stack depth: "
-msgstr ""
+msgstr "حدوث تجاوز للتكدس ( Stack overflow) مع عمق التكدس: "
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Signal Arguments"
@@ -11584,42 +11577,36 @@ msgid "Set Variable Type"
msgstr "تحيد نوع المتغير"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "أضف مدخله"
+msgstr "أضف منفذ أدخال"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "أضف مدخله"
+msgstr "أضف منفذ إخراج"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Override an existing built-in function."
-msgstr "إسم غير صالح، يجب أن لا يتصادم مع الأسماء المبنية تلقائياً الموجودة."
+msgstr "تجاوز لدالة مُدمجة موجودة مسبقًا."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "إنشاء %s جديد"
+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 "إنشاء %s جديد"
+msgstr "إنشاء متغير جديد."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "الإشارات:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "أنشئ شكل جديد من لا شئ."
+msgstr "إنشاء إشارة جديدة."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
@@ -11646,9 +11633,8 @@ msgid "Add Function"
msgstr "إضافة وظيفة برمجية"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "مسح النقطة"
+msgstr "مسح منفذ إدخال"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
@@ -11659,14 +11645,12 @@ msgid "Add Signal"
msgstr "إضافة إشارة"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "مسح النقطة"
+msgstr "حذف منفذ إدخال"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "مسح النقطة"
+msgstr "حذف منفذ إخراج"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
@@ -11750,19 +11734,16 @@ msgid "Connect Nodes"
msgstr "وصل العُقد"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Disconnect 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'"
@@ -11773,9 +11754,8 @@ msgid "Change Input Value"
msgstr "تعديل قيمة الإدخال"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "تعديل العنصر القماشي"
+msgstr "تغيير حجم التعليق"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
@@ -11807,9 +11787,8 @@ msgid "Try to only have one sequence input in selection."
msgstr "حاول أن يكون لديك تسلسل إدخال واحد من المُختار."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "عمل اشتراك"
+msgstr "إنشاء دالة"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
@@ -11832,33 +11811,28 @@ msgid "Editing Signal:"
msgstr "تحرير الإشارة:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Tool:"
-msgstr "أنشئ عظام"
+msgstr "عمل أداة:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
msgstr "الأعضاء:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "غير نوع %s"
+msgstr "تغيير اساس النوع:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "إضافة %s..."
+msgstr "إضافة عُقد..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "مسح المهمة"
+msgstr "إضافة دالة…"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "الإعدادات:"
+msgstr "أسم_الدالة"
#: modules/visual_script/visual_script_editor.cpp
msgid "Select or create a function to edit its graph."
@@ -11881,19 +11855,16 @@ msgid "Cut Nodes"
msgstr "قص العُقد"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "مسح المهمة"
+msgstr "عمل دالة"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "تحديث"
+msgstr "تحديث الرسم البياني"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
-msgstr "الأعضاء"
+msgstr "تعديل العضو"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
@@ -11941,7 +11912,7 @@ msgstr "لم يتم إيجاد (مُحدد المُتغير) VariableSet في ا
#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
-msgstr "العقدة المخصصة لا تحتوي طريقة ()step_ ، لا يمكن معالجة المخطوط."
+msgstr "العقدة المخصصة لا تحتوي طريقة ()step_ ، لا يمكن معالجة الشكل البياني."
#: modules/visual_script/visual_script_nodes.cpp
msgid ""
@@ -11952,9 +11923,8 @@ msgstr ""
"(خطأ)."
#: modules/visual_script/visual_script_property_selector.cpp
-#, fuzzy
msgid "Search VisualScript"
-msgstr "إخلاء الكود"
+msgstr "بحث VisualScript"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
@@ -12009,11 +11979,8 @@ msgstr ""
"الموضوعة سلفاً."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Release keystore incorrectly configured in the export preset."
-msgstr ""
-"مُنقح أخطاء مفتاح المتجر keystore غير مُهيئ في إعدادت المُحرر أو في الإعدادات "
-"الموضوعة سلفاً."
+msgstr "تحرر مخزن المفاتيح غير مُهيئ بشكل صحيح في إعدادت المسبقة للتصدير."
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
@@ -12045,26 +12012,34 @@ msgid ""
"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
"project setting (changed in Godot 3.2.2).\n"
msgstr ""
+"وحدة \"GodotPaymentV3\" المضمنة في إعدادات المشروع \"android / modules\" غير "
+"صالحة (تم تغييره في Godot 3.2.2).\n"
#: platform/android/export/export.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
-msgstr ""
+msgstr "يجب تفعيل \"Use Custom Build\" لإستخدام الإضافات."
#: platform/android/export/export.cpp
msgid ""
"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
"\"."
msgstr ""
+"\"Degrees Of Freedom\" تكون صالحة فقط عندما يكون وضع الـ \"Xr Mode\"هو "
+"\"Oculus Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
msgstr ""
+"\"Hand Tracking\" تكون صالحة فقط عندما يكون وضع الـ \"Xr Mode\"هو \"Oculus "
+"Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
msgstr ""
+"\"Focus Awareness\" تكون صالحة فقط عندما يكون وضع الـ \"Xr Mode\"هو \"Oculus "
+"Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
@@ -12213,13 +12188,12 @@ msgid "Invalid splash screen image dimensions (should be 620x300)."
msgstr "أبعاد شاشة البداية غير صالحة (ينبغي أن تكون 620×300)."
#: scene/2d/animated_sprite.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite to display frames."
msgstr ""
-"ليتم إظهار الأطر (اللقطات) في الAnimatedSprite (النقوش المتحركة), يجب تكوين "
-"مصدر لها من نوع SpriteFrames و ضبط خاصية الFrames (الأطر) بها."
+"ليتم إظهار الإطارات في الAnimatedSprite (النقوش المتحركة), يجب تكوين مصدر "
+"لها من نوع SpriteFrames و ضبط خاصية الFrames (الأطر) بها."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -12255,7 +12229,9 @@ msgstr ""
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
-msgstr "مُضلع تصادم ثنائي الأبعاد فارغ ليس له أي تأثير على التصادم."
+msgstr ""
+"مُضلع تصادم ثنائي الأبعاد (CollisionPolygon2D) الفارغ ليس له أي تأثير على "
+"التصادم."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12263,32 +12239,37 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
-"يعمل مُضلع التصادم ثنائي الأبعاد CollisionPolygon2D فقط كشكل تصادمي لكل العُقد "
-"المشتقة من الكائن التصادمي ثنائي الأبعاد CollisionObject2D. من فضلك استخدمه "
-"فقط لكل أبناء الحيز ثنائي الأبعاد Area2D، الجسم السكوني ثنائي الأبعاد "
-"StaticBody2D و الجسم الجامد ثنائي الأبعاد RigidBody2D، والجسم المتحرك ثنائي "
-"الأبعاد KinematicBody2D إلخ.. لكي تمنح كل منهم شكلاً."
+"يعمل جسم-تصادم-ثنائي-البُعد (CollisionPolygon2D) فقط كشكل تصادمي لكل العُقد "
+"المشتقة من الكائن التصادمي ثنائي الأبعاد (CollisionObject2D). من فضلك "
+"استخدمه فقط لكل أبناء الحيز-ثنائي-البُعد (Area2D)، الجسم-الثابت-ثنائي-البُعد "
+"(StaticBody2D) و الجسم-الصلب-ثنائي-البُعد (RigidBody2D)، والجسم-المتحرك-ثنائي-"
+"البُعد (KinematicBody2D) إلخ.. لكي تمنح كل منهم شكلاً."
#: scene/2d/collision_shape_2d.cpp
msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
msgstr ""
-"يجب تزويد ال CollisionShape2D بإحدى الأشكال (من نوع Shape2D) لتعمل بالشكل "
-"المطلوب. الرجاء تكوين و ضبط الشكل لها اولا!"
+"يجب تزويد جسم-تصادم-ثنائي-البُعد (CollisionShape2D) بإحدى الأشكال (من نوع "
+"Shape2D) لتعمل بالشكل المطلوب. الرجاء تكوين و ضبط الشكل لها اولا!"
#: scene/2d/collision_shape_2d.cpp
msgid ""
"Polygon-based shapes are not meant be used nor edited directly through the "
"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
msgstr ""
+"الأشكال المستندة إلى المضلع (Polygon-based shapes) لا تعني انك قادر على "
+"استخدامها او تعديلها بشكل مباشر من خلال عقدة جسم-تصادم-ثنائي-البُعد "
+"(CollisionShape2D). الرجاء استخدام عقدة مضلع-تصادم-ثنائي-البُعد "
+"(CollisionPolygon2D) بدلاً من ذلك."
#: scene/2d/cpu_particles_2d.cpp
msgid ""
"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
-"تتطلب الرسوم المتحركة CPUParticles2D استخدام CanvasItemMaterial مع تمكين "
+"تتطلب الرسوم المتحركة للجسيمات-وحدة-المعالجة-المركزية-ثنائية-الأبعاد "
+"(CPUParticles2D) استخدام لوحة-مادة-العنصر (CanvasItemMaterial) مع تفعيل"
"\"الرسوم المتحركة للجزيئات\"."
#: scene/2d/light_2d.cpp
@@ -12301,27 +12282,34 @@ msgstr "يجب توريد نقش بهيئة الضوء لخاصية \"النقش
msgid ""
"An occluder polygon must be set (or drawn) for this occluder to take effect."
msgstr ""
+"المُضلع المُغلق(occluder polygon) يجب تعينه (او رسمه) ليأخذ هذا الغَلق تأثيره."
#: scene/2d/light_occluder_2d.cpp
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
-msgstr ""
+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 ""
+"يجب تعيين مصدر مُضلع-التنقل (NavigationPolygon) أو إنشاؤه حتى تعمل هذه "
+"العقدة. يُرجى تعيين خاصية أو رسم مضلع."
#: scene/2d/navigation_polygon.cpp
msgid ""
"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
"node. It only provides navigation data."
msgstr ""
+"يجب أن يكون نموذج-المضلع-المتنقل (NavigationPolygonInstance) تابعًا أو حفيدًا "
+"لعقدة التنقل-ثنائي-الأبعاد (Navigation2D). انه فقط يوفر بيانات التنقل."
#: scene/2d/parallax_layer.cpp
msgid ""
"ParallaxLayer node only works when set as child of a ParallaxBackground node."
msgstr ""
+"تعمل عقدة طبقة-المنظهر (ParallaxLayer) فقط عند تعيينها كعقدة تابعة لعقدة "
+"خلفية-المنظر ParallaxBackground."
#: scene/2d/particles_2d.cpp
msgid ""
@@ -12329,22 +12317,31 @@ msgid ""
"Use the CPUParticles2D node instead. You can use the \"Convert to "
"CPUParticles\" option for this purpose."
msgstr ""
+"لا يدعم برنامج تشغيل الفيديو GLES2 الجسيمات القائمة على وحدة معالجة الرسومات "
+"(GPU-based particles).\n"
+"استخدم عقدة جسيمات-وحدة-المعالجة-المركزية-ثنائية-البُعد (CPUParticles2D) بدلاً "
+"من ذلك. يمكنك استخدام خيار \"التحويل إلى CPUParticles\" لهذا الغرض."
#: 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 ""
+"لا يوجد مادة (material) لمعالجة الجسيمات ، لذلك لا يتم طبع او عمل أي سلوك."
#: scene/2d/particles_2d.cpp
msgid ""
"Particles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"تتطلب الرسوم المتحركة للجسيمات-ثنائية-البُعد (Particles2D) استخدام لوحة-مادة-"
+"العنصر (CanvasItemMaterial) مع تمكين \"الرسوم المتحركة للجسيمات\"."
#: scene/2d/path_2d.cpp
msgid "PathFollow2D only works when set as a child of a Path2D node."
msgstr ""
+"لا يعمل اتباع-المسار-ثنائي-البُعد (PathFollow2D) إلا عند جعل عقدة مسار-ثنائي-"
+"البُعد (Path2D) تابعًا له."
#: scene/2d/physics_body_2d.cpp
msgid ""
@@ -12352,10 +12349,14 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"تغييرات الحجم للجسم-صلب-ثنائي-البُعد (RigidBody2D) (في أوضاع الشخصيات أو "
+"الأوضاع الصلبة) سيتم تجاوزها بواسطة محرك الفيزياء عند التشغيل.\n"
+"قم بتغيير الحجم في أشكال تصادم التابعين له بدلاً من ذلك."
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
msgstr ""
+"يجب أن تشير خاصية المسار إلى عُقدة-ثنائية-البُعد (Node2D) صالحة لكي تعمل."
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
@@ -12366,11 +12367,15 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
msgstr ""
+"يعمل عظم-ثنائي-البُعد (Bone2D) فقط مع هيكلية-ثنائية-البُعد (Skeleton2D) أو "
+"Bone2D آخر كعقدة رئيسية."
#: scene/2d/skeleton_2d.cpp
msgid ""
"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
msgstr ""
+"هذا العظم يفتقر إلى وضع الراحة المناسب. انتقل إلى عقدة هيكلية ثنائية "
+"البُعد(Skeleton2D) وقم بتعيين واحدة."
#: scene/2d/tile_map.cpp
msgid ""
@@ -12378,40 +12383,56 @@ msgid ""
"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
"KinematicBody2D, etc. to give them a shape."
msgstr ""
+"يحتاج خريطة-البلاط (TileMap) مع تفعيل خاصية إستخدام الأصل (Use Parent) إلى "
+"ان يكون تابعًا لكائن-تصادمي-ثنائي-البُعد (CollisionObject2D) لإعطاء الأشكال. "
+"يرجى استخدامه كتابع لحيز-ثنائي-البُعد(ِArea2D)، جسم-ثابت-ثنائي-البُعد "
+"(StaticBody2D)، جسم-صلب-ثنائي-البُعد (RigidBody2D)، أو جسم-متحرك-ثنائي-البُعد "
+"(KinematicBody2D)، وما إلى ذلك لمنحهم شكلاً."
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
+"يعمل مُمَكِن-الرؤية-ثنائي-البُعد (VisibilityEnabler2D) بشكل أفضل عند استخدامه مع "
+"المشهد الرئيس الذي تم تحريره مباشرةً باعتباره الأصل."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "يجب أن تحتوي ARVRCamera على عقدة ARVROrigin كأصل لها."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "يجب أن تحتوي ARVRController على عقدة ARVROrigin كأصل لها."
#: 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 ""
+"يجب ألا يكون معرف وحدة التحكم تساوي 0 أو لن تكون وحدة التحكم هذه مقيدة بوحدة "
+"تحكم فعلية."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "يجب أن يحتوي ARVRController على عقدة ARVROrigin كأصل له."
#: 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 ""
+"يجب ألا يكون معرف الإرتكاز (The anchor) يساوي 0 أو لن يكون هذا الإرتكاز مقيد "
+"بإرتكاز فِعلي."
#: scene/3d/arvr_nodes.cpp
msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
+"يحتاج خريطة-البلاط (TileMap) مع تفعيل خاصية إستخدام الأصل (Use Parent) إلى "
+"ان يكون تابعًا لكائن-تصادمي-ثنائي-البُعد (CollisionObject2D) لإعطاء الأشكال. "
+"يرجى استخدامه كتابع لحيز-ثنائي-البُعد(ِArea2D)، جسم-ثابت-ثنائي-البُعد "
+"(StaticBody2D)، جسم-صلب-ثنائي-البُعد (RigidBody2D)، أو جسم-متحرك-ثنائي-البُعد "
+"(KinematicBody2D)، وما إلى ذلك لمنحهم شكلاً."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -12423,19 +12444,19 @@ msgstr "(الوقت المتبقي: %d:%02d ثانية)"
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Meshes: "
-msgstr ""
+msgstr "تخطيط المجسمات: "
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Lights:"
-msgstr ""
+msgstr "تخطيط الإضاءات:"
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
msgid "Finishing Plot"
-msgstr ""
+msgstr "الانتهاء من التخطيط"
#: scene/3d/baked_lightmap.cpp
msgid "Lighting Meshes: "
-msgstr ""
+msgstr "إضاءة المجسمات: "
#: scene/3d/collision_object.cpp
msgid ""
@@ -12443,6 +12464,8 @@ msgid ""
"Consider adding a CollisionShape or CollisionPolygon as a child to define "
"its shape."
msgstr ""
+"هذه العقدة ليس لها شكل، لذلك لا يمكن أن تصطدم أو تتفاعل مع الكائنات الأخرى.\n"
+"ضع في الإعتبار إضافة شكل تصادم أو مضلع تصادم كتابع لتعريف شكله."
#: scene/3d/collision_polygon.cpp
msgid ""
@@ -12450,6 +12473,10 @@ msgid ""
"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)، جسم صلب (StaticBody)، أو جسم حركي (KinematicBody)، وما "
+"إلى ذلك لمنحهم شكلاً."
#: scene/3d/collision_polygon.cpp
msgid "An empty CollisionPolygon has no effect on collision."
@@ -12461,46 +12488,63 @@ msgid ""
"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)، جسم صلب (StaticBody)، أو جسم حركي (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 ""
-"يجب تزويد ال CollisionShape2D بإحدى الأشكال (من نوع Shape2D) لتعمل بالشكل "
-"المطلوب. الرجاء تكوين و ضبط الشكل لها اولا!"
+"يجب توفير شكل لـ CollisionShape2D بإحدى الأشكال (من نوع Shape2D) لتعمل "
+"بالشكل المطلوب. الرجاء تكوين و ضبط الشكل لها."
#: 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 ""
+"لا تعمل أشكال التبويت (Plane shapes) بشكل جيد وسيتم إزالتها في الإصدارات "
+"المستقبلية. من فضلك لا تستخدمها."
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"الشكل المضلع المُقعر (ConcavePolygonShape) لا يدعم الجسم الصلب (RigidBody) في "
+"أي وضع غير الوضع الثابت."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
-msgstr ""
+msgstr "لا شيء مرئي لأنه لم يتم تعيين أي مجسم."
#: scene/3d/cpu_particles.cpp
msgid ""
"CPUParticles animation requires the usage of a SpatialMaterial whose "
"Billboard Mode is set to \"Particle Billboard\"."
msgstr ""
+"تتطلب الرسوم المتحركة لجسيمات وحدة المعالجة المركزية( CPUParticles) استخدام "
+"مادة مكانية (SpatialMaterial) التي تم ضبط وضع اللوحة (Billboard Mode) الخاص "
+"بها على \"لوحة الجسيمات\"."
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
-msgstr ""
+msgstr "تخطيط المجسمات"
#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
msgstr ""
+"GIProbes لا يدعم برنامج تشغيل الفيديو GLES2.\n"
+"استخدم BakedLightmap بدلاً من ذلك."
+
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -12509,12 +12553,15 @@ msgstr "بقعة الضوء بزاوية أكبر من 90 درجة لا يمكن
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
msgstr ""
+"يجب تعيين مصدر مجسم-التنقل (NavigationMesh) أو إنشاؤه حتى تعمل هذه العقدة."
#: scene/3d/navigation_mesh.cpp
msgid ""
"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
"It only provides navigation data."
msgstr ""
+"يجب أن يكون نموذج-مجسم-التنقل (NavigationMeshInstance) تابعًا أو حفيدًا لعقدة "
+"التنقل (Navigation node). انه يوفر فقط بيانات التنقل."
#: scene/3d/particles.cpp
msgid ""
@@ -12522,17 +12569,23 @@ msgid ""
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
"\" option for this purpose."
msgstr ""
+"الجسيمات القائمة على وحدة معالجة الرسومات (GPU-based particles) لا تدعم "
+"برنامج تشغيل الفيديو GLES2 .\n"
+"استخدم عقدة CPUParticles بدلاً من ذلك. يمكنك استخدام خيار \"التحويل إلى "
+"CPUParticles\" لهذا الغرض."
#: scene/3d/particles.cpp
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
-msgstr ""
+msgstr "لا يوجد شيء مرئي لأن المجسمات لم يتم تعيين لها رسم التمريرات."
#: scene/3d/particles.cpp
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
+"تتطلب الرسوم المتحركة للجسيمات استخدام مادة مكانية (SpatialMaterial) التي تم "
+"ضبط وضع اللوحة (Billboard Mode) الخاص بها على \"لوحة الجسيمات\"."
#: scene/3d/path.cpp
msgid "PathFollow only works when set as a child of a Path node."
@@ -12543,6 +12596,8 @@ msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
msgstr ""
+"يتطلب ROTATION_ORIENTED الخاص بأتباع-المسار (PathFollow) تمكين \"Up Vector\" "
+"في مصدر منحنى مسار الأصل (Parent Path's)."
#: scene/3d/physics_body.cpp
msgid ""
@@ -12550,16 +12605,21 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"تغير حجم الجسم الصلب (RigidBody) (في الشخصية أو الأوضاع الصلبة) سيتم تجاوزها "
+"بواسطة محرك الفيزياء عند التشغيل.\n"
+"قم بتغيير الحجم في أشكال تصادم الأتباع (Children) بدلاً من ذلك."
#: 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 "سيتم تجاهل هذا الجسم حتى تضع تحدد سطحاً mesh."
+msgstr "سيتم تجاهل هذا الجسم حتى تضع تحدد له مجسمًا."
#: scene/3d/soft_body.cpp
msgid ""
@@ -12567,42 +12627,52 @@ msgid ""
"running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"تغير حجم الجسم الناعم (SoftBody) سيتم تجاوزها بواسطة محرك الفيزياء عند "
+"التشغيل.\n"
+"قم بتغيير الحجم في أشكال تصادم الأتباع (Children) بدلاً من ذلك."
#: scene/3d/sprite_3d.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"ليتم إظهار الأطر (اللقطات) في الAnimatedSprite (النقوش المتحركة), يجب تكوين "
-"مصدر لها من نوع SpriteFrames و ضبط خاصية الFrames (الأطر) بها."
+"يجب إنشاء مصدر إطارات الرسم (SpriteFrames) أو تعيينه في خاصية \"الإطارات\" "
+"حتى يتمكن الرسوم المتحركة للرسم ثلاثي الُعد (AnimatedSprite3D) من عرض "
+"الإطارات."
#: 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 ""
+"تعمل عجلة المركبة (VehicleWheel) على توفير نظام عجلات لجسم "
+"المركبة(VehicleBody). يرجى استخدامه كتابع لجسم المركبة."
#: scene/3d/world_environment.cpp
msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"تتطلب بيئة-العالم (WorldEnvironment) خاصية\"البيئة\" الخاصة بها لاحتواء بيئة "
+"ليكون لها تأثير مرئي."
#: scene/3d/world_environment.cpp
msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
-msgstr ""
+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 ""
+"يتم تجاهل هذه البيئة العالمية. إما أن تضيف كاميرا (للمشاهد ثلاثية البُعد) أو "
+"اضبط وضع الخلفية لهذه البيئة على لوحة (Canvas) (للمشاهد ثنائية البُعد)."
#: scene/animation/animation_blend_tree.cpp
msgid "On BlendTree node '%s', animation not found: '%s'"
msgstr ""
+"في عقدة خليط-الشجرة (BlendTree) '%s'، لم يتم العثور على الرسوم المتحركة:'%s '"
#: scene/animation/animation_blend_tree.cpp
msgid "Animation not found: '%s'"
@@ -12679,12 +12749,18 @@ msgid ""
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
+"لا تخدم الحاوية في حد ذاتها أي غرض ما لم يقم النص البرمجي بتكوين سلوك وضع "
+"الأتباع الخاص به .\n"
+"إذا كنت لا تنوي إضافة نص برمجي ، فاستخدم عقدة تحكم عادية بدلاً من ذلك."
#: scene/gui/control.cpp
msgid ""
"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
msgstr ""
+"لن يتم عرض أداة التلميح أثناء تعيين عامل تصفية الفأره الخاص بعنصر التحكم, تم "
+"وضعه على \"تجاهل\". لحل هذه المشكلة ، اضبط تصفية الفأره على \"إيقاف\" أو "
+"\"تمرير\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
@@ -12700,10 +12776,13 @@ msgid ""
"functions. Making them visible for editing is fine, but they will hide upon "
"running."
msgstr ""
+"ستختفي النوافذ المنبثقة افتراضيًا ما لم تقم باستدعاء popup() أو أي من وظائف "
+"popup(). من الجيد جعلها مرئية للتحرير ، لكنها ستختفي عند التشغيل."
#: scene/gui/range.cpp
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
msgstr ""
+"إذا تم تفعيل الـ\"Exp Edit\" يجب على ان يكون \"Min Value\" اعلى من صفر."
#: scene/gui/scroll_container.cpp
msgid ""
@@ -12711,6 +12790,9 @@ msgid ""
"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
"minimum size manually."
msgstr ""
+"تم تصميم ScrollContainer للعمل مع عنصر تحكم تابع واحد.\n"
+"استخدم حاوية كتابع (VBox ، HBox ، إلخ) ، أو عنصر تحكم واضبط الحد الأدنى "
+"المخصص للحجم يدويًا."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -12721,6 +12803,8 @@ msgid ""
"Default Environment as specified in Project Settings (Rendering -> "
"Environment -> Default Environment) could not be loaded."
msgstr ""
+"تعذر تحميل البيئة الافتراضية كما هو محدد في إعدادات المشروع (التقديم -> "
+"البيئة -> البيئة الافتراضية)."
#: scene/main/viewport.cpp
msgid ""
@@ -12729,6 +12813,9 @@ msgid ""
"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
"texture to some node for display."
msgstr ""
+"لم يتم تعيين منفذ العرض هذا كهدف عرض. إذا كنت تنوي عرض محتوياته مباشرة على "
+"الشاشة ، اجعله تابعًا لعنصر تحكم حتى يتمكن من الحصول على الحجم. خلاف ذلك ، "
+"اجعلها RenderTarget وقم بتعيين نسيجها الداخلي لبعض العقد لعرضها."
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
@@ -12762,6 +12849,16 @@ msgstr "يمكن تعيين المتغيرات فقط في الذروة ."
msgid "Constants cannot be modified."
msgstr "لا يمكن تعديل الثوابت."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "رصيف نظام الملفات و الاستيراد"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "حينما يتم التصدير أو النشر، ملف التشغيل الناتج سوف يحاول الإتصال إلي "
+#~ "عنوان الأي بي الخاص بهذا الكمبيوتر من أجل تصحيح الأخطاء."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "المشهد الحالي لم يتم حفظه. الرجاء حفظ المشهد قبل تشغيله و اختباره."
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index b0378d612c..3bb60a79e0 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -8,12 +8,14 @@
# MaresPW <marespw206@gmail.com>, 2018.
# PakoSt <kokotekilata@gmail.com>, 2018, 2020.
# Damyan Dichev <mwshock2@gmail.com>, 2019.
+# Whod <whodizhod@gmail.com>, 2020.
+# Stoyan <stoyan.stoyanov99@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-27 15:42+0000\n"
-"Last-Translator: PakoSt <kokotekilata@gmail.com>\n"
+"PO-Revision-Date: 2020-09-15 07:17+0000\n"
+"Last-Translator: Stoyan <stoyan.stoyanov99@protonmail.com>\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/bg/>\n"
"Language: bg\n"
@@ -21,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -103,7 +105,7 @@ msgstr "Свободно"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Балансиран"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
@@ -192,11 +194,11 @@ msgstr "Промяна на продължителността на анимац
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Промени анимационния цикъл"
#: editor/animation_track_editor.cpp
msgid "Property Track"
-msgstr ""
+msgstr "Път за промяна на свойството"
#: editor/animation_track_editor.cpp
msgid "3D Transform Track"
@@ -516,6 +518,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -643,9 +646,8 @@ msgid "Select All/None"
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"
@@ -696,7 +698,7 @@ msgstr ""
msgid "Whole Words"
msgstr "Цели думи"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Замяна"
@@ -885,6 +887,11 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Поставяне на възелите"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -922,7 +929,7 @@ msgid "Recent:"
msgstr "Последни:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Търсене:"
@@ -1097,6 +1104,9 @@ msgstr "Основатели на проекта"
msgid "Lead Developer"
msgstr "Главен разработчик"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Ръководител на проекта "
@@ -1118,6 +1128,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1581,16 +1599,17 @@ 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 ""
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Показване във файловата система"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Панел за внасяне"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1852,7 +1871,7 @@ msgstr "Папки и файлове:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2678,22 +2697,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2702,8 +2725,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2712,32 +2735,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2797,7 +2820,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Търсене"
@@ -3199,7 +3222,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4239,9 +4263,8 @@ msgid "Anim Clips"
msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Добавяне на нови пътечки."
+msgstr "Аудио клипове"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Functions"
@@ -4402,9 +4425,8 @@ msgid "Onion Skinning Options"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Directions"
-msgstr "Описание:"
+msgstr "Указания"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -4761,9 +4783,8 @@ msgid "Redirect loop."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed, timeout"
-msgstr "Заявката се провали, върнат код:"
+msgstr "Заявката е неуспешна, изчакването е неуспешно"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Timeout."
@@ -4810,9 +4831,8 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Install..."
-msgstr "Инсталиране"
+msgstr "Инсталирате..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
@@ -4882,9 +4902,8 @@ msgid "Import..."
msgstr "Повторно внасяне..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Plugins..."
-msgstr "Приставки"
+msgstr "Приставки ..."
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
msgid "Sort:"
@@ -4900,9 +4919,8 @@ msgid "Site:"
msgstr "Уеб сайт:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Support"
-msgstr "Поддръжка..."
+msgstr "Поддръжка"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -4943,7 +4961,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Преглед"
@@ -4968,9 +4986,8 @@ msgid "steps"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotation Offset:"
-msgstr "Изместване при Завъртане:"
+msgstr "Изместване на въртенето:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
@@ -7590,7 +7607,8 @@ msgid "New Animation"
msgstr "Нова анимация"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Скорост (кадри в секунда):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9643,6 +9661,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Управление на проектите"
@@ -10073,11 +10092,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Замяна: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10123,7 +10147,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10181,8 +10205,9 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Използване на регулярни изрази"
#: editor/rename_dialog.cpp
msgid "At character %s"
@@ -11895,9 +11920,8 @@ msgid "Invalid package publisher display name."
msgstr "невалидно име на Група."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid product GUID."
-msgstr "Име:"
+msgstr "Невалиден продуктов GUID."
#: platform/uwp/export/export.cpp
msgid "Invalid publisher GUID."
@@ -12232,6 +12256,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12488,7 +12517,7 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Константите не могат да бъдат променени."
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 5fdcfb385b..8415bb30bd 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -567,6 +567,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "এফ পি এস"
@@ -755,7 +756,7 @@ msgstr "অক্ষরের মাত্রা (বড়/ছোট-হাতে
msgid "Whole Words"
msgstr "সম্পূর্ণ শব্দ"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "প্রতিস্থাপন করুন"
@@ -964,6 +965,11 @@ msgid "Signals"
msgstr "সংকেতসমূহ"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "দ্রুত ফাইলসমূহ ফিল্টার করুন..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -1006,7 +1012,7 @@ msgid "Recent:"
msgstr "সাম্প্রতিক:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "অনুসন্ধান করুন:"
@@ -1193,6 +1199,9 @@ msgstr "প্রজেক্ট ফাউন্ডার"
msgid "Lead Developer"
msgstr "মূল ডেভেলপার"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
#, fuzzy
msgid "Project Manager "
@@ -1215,6 +1224,16 @@ msgid "Gold Sponsors"
msgstr "গোল্ড স্পনসর"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "সিলভার ডোনার"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "ব্রোঞ্জ ডোনার"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "মিনি স্পনসর"
@@ -1715,21 +1734,21 @@ msgstr "দৃশ্যের শাখা (নোডসমূহ):"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "ইম্পোর্ট"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "মোড (Mode) সরান"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "ফাইলসিস্টেম"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "ইম্পোর্ট"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "সমস্তগুলি প্রতিস্থাপন করুন"
@@ -2021,7 +2040,7 @@ msgstr "পথ এবং ফাইল:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "প্রিভিউ:"
@@ -2957,24 +2976,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"এক্সপোর্ট (Export) বা ডিপ্লয় (Deploy)-এর সময় প্রস্তুতকৃত এক্সিকিউটেবল (executable) "
-"ডিবাগ (debug)-এর উদ্দেশ্যে এই কম্পিউটারের আইপি (IP)-তে সংযোগ করার চেষ্টা করবে।"
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "নেটওয়ার্ক ফাইল-সিস্টেমের সহিত ক্ষুদ্র-ডিপ্লয় করুন"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"এই সিদ্ধান্তটি (অপশন) সক্রিয় করলে, এক্সপোর্ট (Export) বা ডিপ্লয় (Deploy)-এ স্বল্পতম "
"মানের এক্সিকিউটেবল (executable) উৎপাদন হবে।\n"
@@ -2988,9 +3011,10 @@ msgid "Visible Collision Shapes"
msgstr "দৃশ্যমান সাংঘর্ষিক আকারসমূহ (Collision Shapes)"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"এই সিদ্ধান্তটি (অপশন) সক্রিয় করলে চলমান গেমে কলিশ়ন (Collision) আকৃতি এবং রে-কাস্ট "
"(RayCast) নোড (2D এবং 3D) দৃশ্যমান হবে।"
@@ -3000,23 +3024,26 @@ msgid "Visible Navigation"
msgstr "দৃশ্যমান নেভিগেশন (Navigation)"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"এই সিদ্ধান্তটি (অপশন) সক্রিয় করলে চলমান গেমে ন্যাভিগেশন (Navigation) মেস এবং "
"পলিগন-সমূহ দৃশ্যমান হবে।"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "দৃশ্যের পরিবর্তনসমূহ সুসংগত/সমন্বয় করুন"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"এই সিদ্ধান্তটি (অপশন) সক্রিয় থাকলে, এডিটরে কোনো দৃশ্যের পরিবর্তন করলে তা চলমান "
"গেমে প্রতিফলিত হবে।\n"
@@ -3024,15 +3051,17 @@ msgstr ""
"কার্যকর করবে।"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "স্ক্রিপ্টের পরিবর্তনসমূহ সুসংগত/সমন্বয় করুন"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"এই সিদ্ধান্তটি (অপশন) সক্রিয় থাকলে, কোনো স্ক্রিপ্টের পরিবর্তন সংরক্ষণে তা চলমান গেমে "
"প্রতিফলিত হবে।\n"
@@ -3105,7 +3134,7 @@ msgstr "হেল্প"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "অনুসন্ধান করুন"
@@ -3542,9 +3571,11 @@ msgid "Add Key/Value Pair"
msgstr ""
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"কাংখিত প্ল্যাটফর্মের জন্য গ্রহণযোগ্য কোন এক্সপোর্ট প্রিসেট খুঁজে পাওয়া যায়নি।\n"
"অনুগ্রহ করে এক্সপোর্ট মেনুতে একটি সঠিক প্রিসেট যোগ করুন।"
@@ -5482,7 +5513,7 @@ msgid "Bake Lightmaps"
msgstr "লাইট্ম্যাপে হস্তান্তর করুন:"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "প্রিভিউ"
@@ -8326,7 +8357,8 @@ msgid "New Animation"
msgstr "অ্যানিমেশন"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "গতি (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10518,6 +10550,7 @@ msgstr ""
"বিদ্যমান Godot প্রজেক্টের খোঁজে আপনি %s ফোল্ডারসমূহ স্ক্যান করতে যাচ্ছেন। আপনি কি "
"সুনিশ্চিত?"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "প্রজেক্ট ম্যানেজার"
@@ -10979,11 +11012,16 @@ msgid "Batch Rename"
msgstr "পুনঃনামকরণ করুন"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "প্রতিস্থাপন করুন"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11035,7 +11073,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -11099,7 +11137,7 @@ msgstr "সম্প্রসারন/সংকোচন অপসারণ ক
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "অভিব্যক্তি (Expression) পরিবর্তন করুন"
#: editor/rename_dialog.cpp
@@ -13279,6 +13317,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13558,6 +13601,18 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "ফাইলসিস্টেম"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "এক্সপোর্ট (Export) বা ডিপ্লয় (Deploy)-এর সময় প্রস্তুতকৃত এক্সিকিউটেবল "
+#~ "(executable) ডিবাগ (debug)-এর উদ্দেশ্যে এই কম্পিউটারের আইপি (IP)-তে সংযোগ "
+#~ "করার চেষ্টা করবে।"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "বর্তমান দৃশ্যটি কখনোই সংরক্ষণ করা হয় নি, অনুগ্রহ করে চালানোর পূর্বে এটি সংরক্ষণ "
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 359aea8184..629583d816 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -536,6 +536,7 @@ msgid "Seconds"
msgstr "Segons"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -714,7 +715,7 @@ msgstr "Distingeix entre majúscules i minúscules"
msgid "Whole Words"
msgstr "Paraules senceres"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
#, fuzzy
msgid "Replace"
msgstr "Reemplaçar"
@@ -910,6 +911,11 @@ msgid "Signals"
msgstr "Senyals"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrat de Fitxers"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Esteu segur que voleu eliminar totes les connexions d'aquest senyal?"
@@ -947,7 +953,7 @@ msgid "Recent:"
msgstr "Recents:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Cerca:"
@@ -1127,6 +1133,9 @@ msgstr "Fundadors del Projecte"
msgid "Lead Developer"
msgstr "Desenvolupador Principal"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Gestor del Projecte "
@@ -1148,6 +1157,16 @@ msgid "Gold Sponsors"
msgstr "Patrocinadors Gold"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Donants Silver"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Donants Bronze"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Patrocinadors"
@@ -1626,16 +1645,17 @@ msgid "Scene Tree Editing"
msgstr "Edició de l'arbre d'escenes"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importació"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Nodes"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Importació i sistema de fitxers"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistema de Fitxers"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importació"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1899,7 +1919,7 @@ msgstr "Directoris i Fitxers:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Vista prèvia:"
@@ -2787,24 +2807,28 @@ msgstr "Desplegar amb Depuració Remota"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"En ser exportat o desplegat, l'executable resultant intenta connectar-se a "
-"l'IP d'aquest equip per iniciar-ne la depuració."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Desplegament Reduït amb Sistema de Fitxers en Xarxa"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Amb aquesta opció activada, 'Exportar' o 'Desplegar' generen un executable "
"reduït.\n"
@@ -2818,9 +2842,10 @@ msgid "Visible Collision Shapes"
msgstr "Formes de Col·lisió Visibles"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Les formes de col·lisió i nodes de difusió de raigs (raycast) (per a 2D i "
"3D), son visibles durant l'execució del joc quan s'activa aquesta opció."
@@ -2830,23 +2855,26 @@ msgid "Visible Navigation"
msgstr "Navegació Visible"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Aquesta opció fa visibles les malles i polígons de Navegació durant "
"l'execució del joc."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronitzar Canvis en Escena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"En activar aquesta opció, els canvis fets en l'Editor es repliquen en el joc "
"en execució.\n"
@@ -2854,15 +2882,17 @@ msgstr ""
"millora el rendiment."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronitzar Canvis en Scripts"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"En activar aquesta opció, els Scripts, en ser desats, es recarreguen en el "
"joc en execució.\n"
@@ -2928,7 +2958,7 @@ msgstr "Ajuda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Cerca"
@@ -3355,9 +3385,11 @@ msgid "Add Key/Value Pair"
msgstr "Afegeix una Parella de Clau/Valor"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"No s'ha trobat cap patró d'exportació executable per aquesta plataforma. \n"
"Afegiu un patró predeterminat en el menú d'exportació."
@@ -5157,7 +5189,7 @@ msgid "Bake Lightmaps"
msgstr "Precalcular Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Previsualització"
@@ -7893,7 +7925,8 @@ msgid "New Animation"
msgstr "Nova Animació"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocitat (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10136,6 +10169,7 @@ msgstr ""
"existents?\n"
"Això pot trigar una estona."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestor del Projecte"
@@ -10581,11 +10615,18 @@ msgid "Batch Rename"
msgstr "Reanomena"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Reemplaça: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefix"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufix"
#: editor/rename_dialog.cpp
@@ -10635,7 +10676,8 @@ msgid "Per-level Counter"
msgstr "Comptador per nivell"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Si s'estableix el comptador es reinicia per a cada grup de nodes fills"
#: editor/rename_dialog.cpp
@@ -10697,7 +10739,7 @@ msgstr "Resetejar"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "Expressions Regulars"
#: editor/rename_dialog.cpp
@@ -12860,6 +12902,11 @@ msgstr ""
"Les GIProbes no estan suportades pel controlador de vídeo GLES2.\n"
"Utilitzeu un BakedLightmap en el seu lloc."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
#, fuzzy
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -13167,6 +13214,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Les constants no es poden modificar."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Importació i sistema de fitxers"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "En ser exportat o desplegat, l'executable resultant intenta connectar-se "
+#~ "a l'IP d'aquest equip per iniciar-ne la depuració."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "L'escena actual no s'ha desat encara. Desa l'escena abans d'executar-la."
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 0d2ae15065..2839053135 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -21,12 +21,13 @@
# Ondrej Pavelka <ondrej.pavelka@outlook.com>, 2020.
# Zbyněk <zbynek.fiala@gmail.com>, 2020.
# Daniel Kříž <Daniel.kriz@protonmail.com>, 2020.
+# VladimirBlazek <vblazek042@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
-"Last-Translator: Daniel Kříž <Daniel.kriz@protonmail.com>\n"
+"PO-Revision-Date: 2020-09-12 00:46+0000\n"
+"Last-Translator: VladimirBlazek <vblazek042@gmail.com>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/"
"cs/>\n"
"Language: cs\n"
@@ -34,7 +35,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -546,6 +547,7 @@ msgid "Seconds"
msgstr "Sekundy"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -724,7 +726,7 @@ msgstr "Rozlišovat malá/velká"
msgid "Whole Words"
msgstr "Celá slova"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Nahradit"
@@ -916,6 +918,11 @@ msgid "Signals"
msgstr "Signály"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrovat soubory..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Jste si jistí, že chcete odstranit všechna připojení z tohoto signálu?"
@@ -953,7 +960,7 @@ msgid "Recent:"
msgstr "Nedávné:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Hledat:"
@@ -1133,6 +1140,9 @@ msgstr "Zakladatelé projektu"
msgid "Lead Developer"
msgstr "Vedoucí vývojář"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Správce projektu "
@@ -1154,6 +1164,16 @@ msgid "Gold Sponsors"
msgstr "Zlatí sponzoři"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Stříbrní dárci"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronzoví dárci"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Malí sponzoři"
@@ -1622,27 +1642,27 @@ msgstr "Editor skriptů"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr "Otevřít knihovnu assetů"
+msgstr "Knihovna zdrojů (AssetLib)"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
msgstr "Úpravy stromu scény"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importovat dok"
-
-#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Node Dock"
msgstr "Uzel přesunut"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "Souborový systém"
#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importovat dok"
+
+#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
msgstr "Smazat profil '%s'? (bez možnosti vrácení)"
@@ -1903,7 +1923,7 @@ msgstr "Složky a soubory:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Náhled:"
@@ -2553,6 +2573,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Vybraná scéna '%s' neexistuje, vybrat platnou? \n"
+"Později to můžete změnit v \"Nastavení projektu\" v kategorii 'application'."
#: editor/editor_node.cpp
msgid ""
@@ -2769,24 +2791,28 @@ msgstr "Nasazení se vzdáleným laděním"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Při exportu nebo nasazení, se výsledný spustitelný soubor pokusí připojit k "
-"IP tohoto počítače, aby ho bylo možné ladit."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Minimální nasazení se síťovým FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Když je tato možnost povolena, export nebo nasazení bude vytvářet minimální "
"spustitelný soubor.\n"
@@ -2799,9 +2825,10 @@ msgid "Visible Collision Shapes"
msgstr "Viditelné kolizní tvary"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Kolizní tvary a raycast uzly (pro 2D a 3D) budou viditelné během hry, po "
"aktivaci této volby."
@@ -2811,22 +2838,25 @@ msgid "Visible Navigation"
msgstr "Viditelná navigace"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigační meshe a polygony budou viditelné během hry, po aktivaci této volby."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synchronizovat změny scény"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Když je zapnuta tato možnost, všechny změny provedené ve scéně v editoru "
"budou replikovány v běžící hře.\n"
@@ -2834,15 +2864,17 @@ msgstr ""
"síťového souborového systému."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synchornizace změn skriptu"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Když je zapnuta tato volba, jakýkoliv skript, který je uložen bude znovu "
"nahrán do spuštěné hry.\n"
@@ -2909,7 +2941,7 @@ msgstr "Nápověda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Hledat"
@@ -3173,7 +3205,7 @@ msgstr "Fyzikální snímek %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
-msgstr ""
+msgstr "Inkluzivní"
#: editor/editor_profiler.cpp
msgid "Self"
@@ -3312,9 +3344,11 @@ msgid "Add Key/Value Pair"
msgstr "Vložte pár klíč/hodnota"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Nebylo nalezeno žádné spustilené přednastavení pro exportování na tuto "
"platformu.\n"
@@ -3352,8 +3386,9 @@ msgstr ""
"podpisu."
#: editor/editor_sub_scene.cpp
+#, fuzzy
msgid "Select Node(s) to Import"
-msgstr ""
+msgstr "Vyberte uzly (Node) pro import"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
@@ -3361,7 +3396,7 @@ msgstr "Procházet"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
-msgstr ""
+msgstr "Cesta ke scéně:"
#: editor/editor_sub_scene.cpp
msgid "Import From Node:"
@@ -3933,16 +3968,17 @@ msgid "Running Custom Script..."
msgstr ""
#: editor/import/resource_importer_scene.cpp
+#, fuzzy
msgid "Couldn't load post-import script:"
-msgstr ""
+msgstr "Nepodařilo se načíst post-import script:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
-msgstr ""
+msgstr "Neplatný/rozbitý skript pro post-import (viz konzole):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
-msgstr ""
+msgstr "Chyba při spuštění post-import scriptu:"
#: editor/import/resource_importer_scene.cpp
msgid "Did you return a Node-derived object in the `post_import()` method?"
@@ -4027,7 +4063,7 @@ msgstr ""
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
-msgstr ""
+msgstr "Udělat Sub-prostředky unikátní"
#: editor/inspector_dock.cpp
msgid "Open in Help"
@@ -4407,7 +4443,7 @@ msgstr "Povolit filtrování"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
-msgstr ""
+msgstr "Zapnout Autoplay"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
@@ -4450,7 +4486,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
-msgstr ""
+msgstr "Změnit Blend Time"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Load Animation"
@@ -4505,8 +4541,9 @@ msgid "Animation position (in seconds)."
msgstr "Pozice animace (v sekundách)."
#: editor/plugins/animation_player_editor_plugin.cpp
+#, fuzzy
msgid "Scale animation playback globally for the node."
-msgstr ""
+msgstr "Škálovat playback animace globálně pro uzel"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
@@ -4529,8 +4566,9 @@ msgid "Display list of animations in player."
msgstr "Zobrazit seznam animací v přehrávači."
#: editor/plugins/animation_player_editor_plugin.cpp
+#, fuzzy
msgid "Autoplay on Load"
-msgstr ""
+msgstr "Autoplay při načtení"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Enable Onion Skinning"
@@ -4607,7 +4645,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Next (Auto Queue):"
-msgstr ""
+msgstr "Další (Automatická řada):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
@@ -4721,8 +4759,9 @@ msgid "Scale:"
msgstr "Zvětšení:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Fade In (s):"
-msgstr ""
+msgstr "Zmizení do (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Fade Out (s):"
@@ -4742,11 +4781,11 @@ msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Restart (s):"
-msgstr ""
+msgstr "Restart (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Random Restart (s):"
-msgstr ""
+msgstr "Náhodný Restart (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Start!"
@@ -4781,7 +4820,7 @@ msgstr "Přidat vstup"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Clear Auto-Advance"
-msgstr ""
+msgstr "Čistý Auto-Advance"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Set Auto-Advance"
@@ -5072,7 +5111,7 @@ msgid "Bake Lightmaps"
msgstr "Zapéct lightmapy"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Náhled"
@@ -7754,7 +7793,8 @@ msgid "New Animation"
msgstr "Nová animace"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Rychlost (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9872,6 +9912,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Správce projektů"
@@ -10318,11 +10359,18 @@ msgid "Batch Rename"
msgstr "Dávkové přejmenování"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Nahradit: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefix"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufix"
#: editor/rename_dialog.cpp
@@ -10370,7 +10418,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10430,7 +10478,8 @@ msgid "Reset"
msgstr "Resetovat"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Chyba regulárního výrazu"
#: editor/rename_dialog.cpp
@@ -12473,6 +12522,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12758,6 +12812,17 @@ msgstr "Odlišnosti mohou být přiřazeny pouze ve vertex funkci."
msgid "Constants cannot be modified."
msgstr "Konstanty není možné upravovat."
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Souborový systém"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Při exportu nebo nasazení, se výsledný spustitelný soubor pokusí připojit "
+#~ "k IP tohoto počítače, aby ho bylo možné ladit."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Aktuální scéna nebyla nikdy uložena, prosím uložte jí před spuštěním."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index da54615917..95a5d793e0 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -560,6 +560,7 @@ msgid "Seconds"
msgstr "Sekunder"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -743,7 +744,7 @@ msgstr "Match stor/lille"
msgid "Whole Words"
msgstr "Hele Ord"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Erstat"
@@ -947,6 +948,11 @@ msgid "Signals"
msgstr "Signaler"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrer filer..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Er du sikker på at du vil fjerne alle forbindelser fra dette signal?"
@@ -984,7 +990,7 @@ msgid "Recent:"
msgstr "Seneste:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Søgning:"
@@ -1168,6 +1174,9 @@ msgstr "Projekt grundlæggere"
msgid "Lead Developer"
msgstr "Ledende Udvikler"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projektleder "
@@ -1189,6 +1198,16 @@ msgid "Gold Sponsors"
msgstr "Guld Sponsorer"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Sølv Donorer"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronze Donorer"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsorer"
@@ -1679,21 +1698,21 @@ msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Importer"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "Node Navn:"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "Fil System"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "Importer"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "Erstat Alle"
@@ -1980,7 +1999,7 @@ msgstr "Mapper & Filer:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Forhåndsvisning:"
@@ -2874,24 +2893,28 @@ msgstr "Indsætte med Fjern Fejlfind"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Ved eksport eller deploy, vil den resulterende eksekverbare fil forsøge at "
-"oprette forbindelse til denne computers IP adresse for at blive debugged."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Lille Indsættelse med Nætværks FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Når denne indstilling er aktiveret, vil eksport eller deploy producere en "
"minimal eksekverbar.\n"
@@ -2904,9 +2927,10 @@ msgid "Visible Collision Shapes"
msgstr "Synlig Kollisionsformer"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Kollisionsformer og raycast-noder (til 2D og 3D) vil være synlige på det "
"kørende spil, hvis denne indstilling er tændt."
@@ -2916,23 +2940,26 @@ msgid "Visible Navigation"
msgstr "Synlig Navigation"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigationsmasker og polygoner vil være synlige på det kørende spil, hvis "
"denne indstilling er tændt."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synkroniser Scene Ændringer"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Når denne indstilling er tændt, vil eventuelle ændringer til scenen i "
"editoren blive overført til det kørende spil.\n"
@@ -2940,15 +2967,17 @@ msgstr ""
"filsystem."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synkroniser Script Ændringer"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Når denne indstilling er tændt, genindlæses gemte script, på det kørende "
"spil.\n"
@@ -3018,7 +3047,7 @@ msgstr "Hjælp"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Søg"
@@ -3429,9 +3458,11 @@ msgid "Add Key/Value Pair"
msgstr ""
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Ingen kørbare eksport forudindstillinger fundet til denne platform.\n"
"Tilføj venligst en kørbar forudindstilling i eksportmenuen."
@@ -5294,7 +5325,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -8010,7 +8041,7 @@ msgid "New Animation"
msgstr "Ny Animation Navn:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10109,9 +10140,10 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
-msgstr "Projektleder"
+msgstr "Projekt Manager"
#: editor/project_manager.cpp
#, fuzzy
@@ -10553,11 +10585,16 @@ msgid "Batch Rename"
msgstr "Omdøb"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Erstat"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10608,7 +10645,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10670,7 +10707,7 @@ msgstr "Nulstil Zoom"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "Skift udtryk"
#: editor/rename_dialog.cpp
@@ -12758,6 +12795,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13037,6 +13079,18 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke ændres."
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Fil System"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Ved eksport eller deploy, vil den resulterende eksekverbare fil forsøge "
+#~ "at oprette forbindelse til denne computers IP adresse for at blive "
+#~ "debugged."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Den nuværende scene er aldrig gemt, venligst gem før du kører den."
diff --git a/editor/translations/de.po b/editor/translations/de.po
index 081dfb8e4f..082f22322b 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -55,12 +55,17 @@
# Günther Bohn <ciscouser@gmx.de>, 2020.
# Tom Wor <mail@tomwor.com>, 2020.
# Bjarne Hiller <bjarne.hiller@gmail.com>, 2020.
+# Dirk Federmann <weblategodot@dirkfedermann.de>, 2020.
+# Helmut Hirtes <helmut.h@gmx.de>, 2020.
+# Michal695 <michalek.jedrzejak@gmail.com>, 2020.
+# Leon Marz <leon.marz@kabelmail.de>, 2020.
+# Patric Wust <patric.wust@gmx.de>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-05 16:58+0000\n"
-"Last-Translator: Bjarne Hiller <bjarne.hiller@gmail.com>\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
+"Last-Translator: Patric Wust <patric.wust@gmx.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -68,7 +73,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -77,13 +82,13 @@ msgstr "Ungültiger Argument-Typ in convert(), TYPE_*-Konstanten benötigt."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "Zeichenkette der Länge 1 erwartet (exakt ein Symbol)."
+msgstr "Zeichenkette der Länge 1 erwartet (exakt ein Zeichen)."
#: 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 "Nicht genügend Bytes zum Dekodieren oder ungültiges Format."
+msgstr "Nicht genügend Bytes zur Dekodierung oder ungültiges Format."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -581,6 +586,7 @@ msgid "Seconds"
msgstr "Sekunden"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -759,7 +765,7 @@ msgstr "Groß-/Kleinschreibung berücksichtigen"
msgid "Whole Words"
msgstr "Ganze Wörter"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Ersetzen"
@@ -952,6 +958,11 @@ msgid "Signals"
msgstr "Signale"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Kacheln filtern"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Sollen wirklich alle Verbindungen mit diesem Signal entfernt werden?"
@@ -989,7 +1000,7 @@ msgid "Recent:"
msgstr "Kürzlich:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Suche:"
@@ -1173,9 +1184,12 @@ msgstr "Projektgründer"
msgid "Lead Developer"
msgstr "Hauptentwickler"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Projektverwaltung "
+msgstr "Projektleiter "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1194,6 +1208,14 @@ msgid "Gold Sponsors"
msgstr "Gold-Sponsoren"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Silber-Sponsoren"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Bronze-Sponsoren"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini-Sponsoren"
@@ -1660,27 +1682,28 @@ msgstr "3D-Editor"
#: editor/editor_feature_profile.cpp
msgid "Script Editor"
-msgstr "Skripteditor"
+msgstr "Skript Editor"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr "Nutzerinhaltesammlung"
+msgstr "Bestandsbibliothek"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
msgstr "Szenenbaum-Bearbeitung"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importleiste"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Node-Leiste"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Dateisystem- und Import-Leiste"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Dateisystem"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importleiste"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1945,7 +1968,7 @@ msgstr "Verzeichnisse & Dateien:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Vorschau:"
@@ -2129,7 +2152,7 @@ msgstr "Eigenschaft:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr "Festlegen"
+msgstr "Set"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
@@ -2828,7 +2851,7 @@ msgstr "Zur Projektverwaltung zurückkehren"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr "Debuggen"
+msgstr "Fehlersuche (debuggen)"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -2836,24 +2859,28 @@ msgstr "Mit Fern-Fehlerbehebung starten"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Beim Exportieren oder Starten wird das Programm versuchen, sich mit der IP-"
-"Adresse dieses Computers zu verbinden, um Fehler beheben zu können."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Kleine Programmdatei über ein Netzwerkdateisystem"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Wenn diese Option aktiviert ist, wird das Exportieren bzw. Starten nur eine "
"kleine Programmdatei erzeugen.\n"
@@ -2867,9 +2894,10 @@ msgid "Visible Collision Shapes"
msgstr "Collision-Shapes sichtbar"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Collision-Shapes und Raycast-Nodes (für 2D und 3D) werden im laufenden Spiel "
"angezeigt, falls diese Option aktiviert ist."
@@ -2879,23 +2907,26 @@ msgid "Visible Navigation"
msgstr "Navigation sichtbar"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigations- Meshes und Polygone werden im laufenden Spiel sichtbar sein "
"wenn diese Option gewählt ist."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Szenenänderungen synchronisieren"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Wenn diese Option gewählt ist, werden jegliche Änderungen der Szene im "
"Editor im laufenden Spiel dargestellt.\n"
@@ -2903,15 +2934,17 @@ msgstr ""
"effizientesten das Netzwerk-Dateisystem zu nutzen."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Skriptänderungen synchronisieren"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Wenn diese Option gewählt ist, werden erneut gespeicherte Skripte während "
"des laufenden Spiels neu geladen.\n"
@@ -2976,7 +3009,7 @@ msgstr "Hilfe"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Suchen"
@@ -2999,7 +3032,7 @@ msgstr "Dokumentationsvorschläge senden"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "Gemeinschaft"
+msgstr "Community"
#: editor/editor_node.cpp
msgid "About"
@@ -3011,7 +3044,7 @@ msgstr "Projekt abspielen."
#: editor/editor_node.cpp
msgid "Play"
-msgstr "Starten"
+msgstr "Abspielen"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
@@ -3031,7 +3064,7 @@ msgstr "Spiele die bearbeitete Szene."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Szene starten"
+msgstr "Szene abspielen"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -3039,7 +3072,7 @@ msgstr "Spiele angepasste Szene"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr "Spiele angepasste Szene"
+msgstr "Angepasste Szene abspielen"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
@@ -3256,7 +3289,7 @@ msgstr "Gesamt"
#: editor/editor_profiler.cpp
msgid "Self"
-msgstr "Eigenanteil"
+msgstr "Selbst"
#: editor/editor_profiler.cpp
msgid "Frame #:"
@@ -3395,9 +3428,11 @@ msgid "Add Key/Value Pair"
msgstr "Schlüssel-Wert-Paar hinzufügen"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Keine Soforteinsatz-Exportvorlage für diese Plattform gefunden.\n"
"Im Exportmenü kann eine Vorlage als Soforteinsatz markiert werden."
@@ -5173,7 +5208,7 @@ msgid "Bake Lightmaps"
msgstr "Lightmaps vorrendern"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Vorschau"
@@ -5695,7 +5730,7 @@ msgstr "Pose kopieren"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
-msgstr "Pose zurücksetzen"
+msgstr "Pose/Stellung löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
@@ -6833,7 +6868,7 @@ msgstr "Schiebe hoch"
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Down"
-msgstr "Schiebe herunter"
+msgstr "Schiebe runter"
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
@@ -6878,7 +6913,7 @@ msgstr "Vorwärts im Verlauf"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme"
-msgstr "Theme"
+msgstr "Designvorlagen (Thema)"
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme..."
@@ -7110,7 +7145,7 @@ msgstr "Symbol vervollständigen"
#: editor/plugins/script_text_editor.cpp
msgid "Evaluate Selection"
-msgstr "Auswahl auswerten"
+msgstr "Springe zum vorigen Haltepunkt"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
@@ -7836,7 +7871,8 @@ msgid "New Animation"
msgstr "Neue Animation"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Geschwindigkeit (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9398,9 +9434,9 @@ msgid ""
"Returns falloff based on the dot product of surface normal and view "
"direction of camera (pass associated inputs to it)."
msgstr ""
-"Gibt den Fresnelabfall abgeleitet aus dem Skalarprodukt aus "
-"Oberflächennormalenvektor und Kamerablickrichtung zurück (zugeordnete "
-"Eingänge müssen übergeben werden)."
+"Gibt den Abfall basierend auf dem Punktprodukt der Oberflächennormalen und "
+"der Blickrichtung der Kamera zurück (übergeben Sie die zugehörigen Eingaben "
+"an diese)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9972,6 +10008,7 @@ msgstr ""
"Sollen wirklich %s Ordner nach Godot-Projekten durchsucht werden?\n"
"Dies kann eine Weile dauern."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projektverwaltung"
@@ -10323,7 +10360,7 @@ msgstr "Umleitungen nach Lokalisierung:"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Lokalisierung"
+msgstr "Gebietsschema"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -10414,11 +10451,18 @@ msgid "Batch Rename"
msgstr "Stapelweise Umbenennung"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Ersetzen: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefix"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Suffix"
#: editor/rename_dialog.cpp
@@ -10466,7 +10510,8 @@ msgid "Per-level Counter"
msgstr "Pro-Ebene-Zähler"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
"Falls gesetzt startet dieser Zähler für jede Gruppe aus Unterobjekten neu"
@@ -10527,7 +10572,8 @@ msgid "Reset"
msgstr "Zurücksetzen"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Fehler in regulärem Ausdruck"
#: editor/rename_dialog.cpp
@@ -10756,7 +10802,7 @@ msgstr "Unter-Ressourcen"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance"
-msgstr "Leere Vererbung"
+msgstr "Löse Vererbung"
#: editor/scene_tree_dock.cpp
msgid "Editable Children"
@@ -10845,7 +10891,7 @@ msgstr "Lokal"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance? (No Undo!)"
-msgstr "Vererbung wirklich leeren? (Lässt sich nicht rückgängig machen!)"
+msgstr "Vererbung wirklich lösen? (Lässt sich nicht rückgängig machen!)"
#: editor/scene_tree_editor.cpp
msgid "Toggle Visible"
@@ -11926,7 +11972,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr "Ausgewähltes löschen"
+msgstr "Auswahl löschen"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
@@ -11942,7 +11988,7 @@ msgstr "Nodes trennen"
#: modules/visual_script/visual_script_editor.cpp
msgid "Make Function"
-msgstr "Funktion bauen"
+msgstr "Funktion erstellen"
#: modules/visual_script/visual_script_editor.cpp
msgid "Refresh Graph"
@@ -12627,6 +12673,11 @@ msgstr ""
"GIProbes werden vom GLES2-Videotreiber nicht unterstützt.\n"
"BakedLightmaps können als Alternative verwendet werden."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12949,6 +13000,16 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden."
msgid "Constants cannot be modified."
msgstr "Konstanten können nicht verändert werden."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Dateisystem- und Import-Leiste"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Beim Exportieren oder Starten wird das Programm versuchen, sich mit der "
+#~ "IP-Adresse dieses Computers zu verbinden, um Fehler beheben zu können."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Die aktuelle Szene wurde noch nicht gespeichert, bitte vor dem Abspielen "
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 87dca17afd..743e77d7dd 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -502,6 +502,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -680,7 +681,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -869,6 +870,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -906,7 +911,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1080,6 +1085,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1101,6 +1109,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1564,15 +1580,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1835,7 +1851,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2660,22 +2676,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2684,8 +2704,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2694,32 +2714,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2779,7 +2799,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3179,7 +3199,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4903,7 +4924,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7485,7 +7506,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9461,6 +9482,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9891,11 +9913,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9941,7 +9967,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -9999,7 +10025,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11928,6 +11954,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 7c2a202767..2571598414 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -536,6 +536,7 @@ msgid "Seconds"
msgstr "Δευτερόλεπτα"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -714,7 +715,7 @@ msgstr "Αντιστοίχηση πεζών-κεφαλαίων"
msgid "Whole Words"
msgstr "Ολόκληρες λέξεις"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Αντικατάσταση"
@@ -908,6 +909,11 @@ msgid "Signals"
msgstr "Σήματα"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Φιλτράρισμα πλακιδίων"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
"Είστε σίγουροι πως θέλετε να αφαιρέσετε όλες της συνδέσεις απο αυτό το σήμα;"
@@ -946,7 +952,7 @@ msgid "Recent:"
msgstr "Πρόσφατα:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Αναζήτηση:"
@@ -1126,6 +1132,9 @@ msgstr "Ιδρυτές του έργου"
msgid "Lead Developer"
msgstr "Επικεφαλής προγραμματιστής"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Διαχειριστής έργων "
@@ -1147,6 +1156,16 @@ msgid "Gold Sponsors"
msgstr "Χρυσοί Χορυγοί"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Αργυροί Δωρητές"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Χάλκινοι Δωρητές"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Μικροί Χορηγοί"
@@ -1625,16 +1644,17 @@ 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 "Πλατφόρμες Συστήματος Αρχείων και Εισαγωγής"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Σύστημα αρχείων"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Πλατφόρμα Εισαγωγής"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1897,7 +1917,7 @@ msgstr "Φάκελοι & Αρχεία:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Προεπισκόπηση:"
@@ -2786,24 +2806,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Όταν εξάγετε ή αναπτύσσετε, το παραγόμενο εκτελέσιμο θα προσπαθήσει να "
-"συνδεθεί στην IP αυτού του υπολογιστή για να αποσφαλματωθεί."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Μικρή ανάπτυξη με δικτυωμένο σύστημα αρχείων"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Όταν ενεργοποιείται αυτή η επιλογή, η εξαγωγή ή η ανάπτυξη θα παράξουν ένα "
"ελαχιστοποιημένο εκτελέσιμο.\n"
@@ -2817,9 +2841,10 @@ msgid "Visible Collision Shapes"
msgstr "Ορατά σχήματα σύγκρουσης"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Σχήματα σύγκρουσης και κόμβοι raycast (για 2D και 3D) θα είναι ορατά στο "
"παιχνίδι εάν αυτή η επιλογή είναι ενεργοποιημένη."
@@ -2829,23 +2854,26 @@ msgid "Visible Navigation"
msgstr "Ορατή πλοήγηση"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Τα πλέγματα πλοήγησης και τα πολύγονα θα είναι ορατά στο παιχνίδι εάν αυτή η "
"επιλογή είναι ενεργοποιημένη."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Συγχρονισμός αλλαγών στη σκηνή"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Η ενεργοποίηση της επιλογής αυτής θα συγχρονίσει αλλαγές της σκηνής εντός "
"του επεξεργαστή με το παιχνίδι που εκτελείται.\n"
@@ -2853,15 +2881,17 @@ msgstr ""
"σύστημα αρχείων."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Συγχρονισμός αλλαγών στις δεσμές ενεργειών"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Η ενεργοποίηση της επιλογής αυτής θα συγχρονίσει κάθε δέσμη ενεργειών που "
"αποθηκεύεται με το παιχνίδι που εκτελείται.\n"
@@ -2927,7 +2957,7 @@ msgstr "Βοήθεια"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Αναζήτηση"
@@ -3347,9 +3377,11 @@ msgid "Add Key/Value Pair"
msgstr "Προσθήκη ζεύγους κλειδιού/τιμής"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Δεν βρέθηκε εκτελέσιμη διαμόρφωση εξαγωγής για αυτή την πλατφόρμα.\n"
"Παρακαλούμε προσθέστε μία εκτελέσιμη διαμόρφωση στο μενού εξαγωγής."
@@ -5127,7 +5159,7 @@ msgid "Bake Lightmaps"
msgstr "Προετοιμασία Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Προεπισκόπηση"
@@ -7793,7 +7825,8 @@ msgid "New Animation"
msgstr "Νέα Κίνηση"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Ταχύτητα (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9924,6 +9957,7 @@ msgstr ""
"Θέλετε να σαρώσετε %s φακέλους για υπαρκτά έργα Godot;\n"
"Αυτό μπορεί να πάρει κάποια ώρα."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Διαχειριστής"
@@ -10364,11 +10398,18 @@ msgid "Batch Rename"
msgstr "Ομαδική Μετονομασία"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Αντικατάσταση: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Πρόθεμα"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Επίθεμα"
#: editor/rename_dialog.cpp
@@ -10416,7 +10457,8 @@ msgid "Per-level Counter"
msgstr "Μετρητής Ανά Επίπεδο"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Εάν ο μετρητής επανεκκινείται για κάθε ομάδα παιδικών κόμβων"
#: editor/rename_dialog.cpp
@@ -10476,7 +10518,8 @@ msgid "Reset"
msgstr "Επαναφορά"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Σφάλμα Κανονικής Εκφράσεως"
#: editor/rename_dialog.cpp
@@ -12582,6 +12625,11 @@ msgstr ""
"Τα GIProbes δεν υποστηρίζονται από το πρόγραμμα οδήγησης οθόνης GLES2.\n"
"Εναλλακτικά, χρησιμοποιήστε ένα BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12894,6 +12942,16 @@ msgstr "Τα «varying» μπορούν να ανατεθούν μόνο στη
msgid "Constants cannot be modified."
msgstr "Οι σταθερές δεν μπορούν να τροποποιηθούν."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Πλατφόρμες Συστήματος Αρχείων και Εισαγωγής"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Όταν εξάγετε ή αναπτύσσετε, το παραγόμενο εκτελέσιμο θα προσπαθήσει να "
+#~ "συνδεθεί στην IP αυτού του υπολογιστή για να αποσφαλματωθεί."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Η τρέχουσα σκηνή δεν έχει αποθηκευτεί, αποθηκεύστε πριν να τρέξετε το "
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index e740ea7d7a..68dbd4f436 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -531,6 +531,7 @@ msgid "Seconds"
msgstr "Sekundoj"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -713,7 +714,7 @@ msgstr "Kongrui Usklon"
msgid "Whole Words"
msgstr "Plenaj Vortoj"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Anstataŭigi"
@@ -908,6 +909,11 @@ msgid "Signals"
msgstr "Signaloj"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtri nodojn"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -945,7 +951,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Serĉo:"
@@ -1119,6 +1125,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1140,6 +1149,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1610,16 +1627,17 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Enporti dokon"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Dosiersistema kaj enporta dokoj"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Dosiersistemo"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Enporti dokon"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1885,7 +1903,7 @@ msgstr "Dosierujoj kaj dosieroj:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2737,24 +2755,28 @@ msgstr "Disponigii kun defora sencimigo"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Kiam eksportas aŭ malfaldas, la rezulta plenumebla provos konekti al la IP "
-"de ĉi tiu komputilo por estos sencimigita."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Eta disponigo kun reta dosiersistemo"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Kiam ĉi tiun agordon estas ŝaltita, eksporti aŭ malfaldi produktos minimuman "
"plenumeblan dosieron.\n"
@@ -2767,9 +2789,10 @@ msgid "Visible Collision Shapes"
msgstr "Videblaj koliziaj formoj"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Koliziaj formoj kaj radĵetaj nodoj (por 2D kaj 3D) estos videblaj en la "
"rulas ludo, se ĉi tiu agordo estas ŝaltita."
@@ -2779,38 +2802,43 @@ msgid "Visible Navigation"
msgstr "Videbla navigacio"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigaciaj maŝoj kaj poligonoj estos videblaj en la rulas ludo, se ĉi tiu "
"agordo estas ŝaltita."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sinkronigi scenan ŝanĝojn"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kiam tuin ĉi agordo estas ŝaltita, iuj ŝanĝoj ke faris al la scenon en la "
"editilo replikos en la rulas ludo.\n"
"Kiam uzantis malproksime en aparato, estas pli efika kun reta dosiersistemo."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sinkronigi skriptajn ŝanĝojn"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kiam tuin ĉi agordo estas ŝaltita, iun skripton ke konservita, estos "
"reŝarĝita en la rulas ludo.\n"
@@ -2873,7 +2901,7 @@ msgstr "Helpo"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Serĉo"
@@ -3278,7 +3306,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5016,7 +5045,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7611,7 +7640,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9610,6 +9639,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10041,11 +10071,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Anstataŭigi: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10091,7 +10126,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10149,7 +10184,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12101,6 +12136,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12354,6 +12394,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstantoj ne povas esti modifitaj."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Dosiersistema kaj enporta dokoj"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Kiam eksportas aŭ malfaldas, la rezulta plenumebla provos konekti al la "
+#~ "IP de ĉi tiu komputilo por estos sencimigita."
+
#~ msgid "Revert"
#~ msgstr "Malfari"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 172ce58604..fa8391cf89 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -50,12 +50,13 @@
# Pedro J. Estébanez <pedrojrulez@gmail.com>, 2020.
# paco <pacosoftfree@protonmail.com>, 2020.
# Jonatan <arandajonatan94@tuta.io>, 2020.
+# ACM <albertocm@tuta.io>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-31 03:47+0000\n"
-"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
+"PO-Revision-Date: 2020-09-12 00:46+0000\n"
+"Last-Translator: ACM <albertocm@tuta.io>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -63,7 +64,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -580,6 +581,7 @@ msgid "Seconds"
msgstr "Segundos"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -758,7 +760,7 @@ msgstr "Coincidir Mayús./Minús."
msgid "Whole Words"
msgstr "Palabras Completas"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Reemplazar"
@@ -952,6 +954,11 @@ msgid "Signals"
msgstr "Señales"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrar tiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
"¿Estás seguro/a que quieres eliminar todas las conexiones de esta señal?"
@@ -990,7 +997,7 @@ msgid "Recent:"
msgstr "Recientes:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Buscar:"
@@ -1172,9 +1179,12 @@ msgstr "Fundadores del Proyecto"
msgid "Lead Developer"
msgstr "Desarrollador Principal"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Administrador del Proyecto "
+msgstr "Gestor del Proyecto "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1193,6 +1203,14 @@ msgid "Gold Sponsors"
msgstr "Patrocinadores Oro"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Patrocinadores Plata"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Patrocinadores Bronce"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Patrocinadores"
@@ -1670,16 +1688,17 @@ msgid "Scene Tree Editing"
msgstr "Editor del Árbol de Escenas"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importación"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Nodos"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Sistema de Archivo e Importación"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistema de Archivos"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importación"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1945,7 +1964,7 @@ msgstr "Directorios y Archivos:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Vista Previa:"
@@ -2833,24 +2852,28 @@ msgstr "Exportar con Depuración Remota"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Al exportar o distribuir, el ejecutable generado intentará conectarse a la "
-"IP de este equipo para ser depurado."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Exportación Mini con Recursos en Red"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Cuando esta opción está activa, al exportar o publicar se creará un "
"ejecutable mínimo.\n"
@@ -2863,9 +2886,10 @@ msgid "Visible Collision Shapes"
msgstr "Ver Formas de Colisión"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Las formas de colisión y los nodos raycast (para 2D y 3D) serán visibles "
"durante la ejecución del juego si esta opción está activada."
@@ -2875,23 +2899,26 @@ msgid "Visible Navigation"
msgstr "Navegación Visible"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Las mallas de navegación y los polígonos serán visibles durante la ejecución "
"del juego si esta opción está activada."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizar cambios de escena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Cuando esta opción este activada, cualquier cambio hecho a la escena en el "
"editor sera replicado en el juego en ejecución.\n"
@@ -2899,15 +2926,17 @@ msgstr ""
"sistema de archivos remoto."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizar Cambios en Scripts"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Cuando esta opción esté activa, cualquier script que se guarde se volverá a "
"cargar en el juego en ejecución.\n"
@@ -2973,7 +3002,7 @@ msgstr "Ayuda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Buscar"
@@ -3394,9 +3423,11 @@ msgid "Add Key/Value Pair"
msgstr "Agregar Par Clave/Valor"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"No se ha encontrado ningún preset de exportación ejecutable para esta "
"plataforma.\n"
@@ -5173,7 +5204,7 @@ msgid "Bake Lightmaps"
msgstr "Bake Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Vista Previa"
@@ -7831,7 +7862,8 @@ msgid "New Animation"
msgstr "Nueva Animación"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocidad (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9965,6 +9997,7 @@ msgstr ""
"existentes?\n"
"Esto puede tardar un poco."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Administrador de Proyectos"
@@ -10405,11 +10438,18 @@ msgid "Batch Rename"
msgstr "Renombrar por lote"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Reemplazar: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefijo"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufijo"
#: editor/rename_dialog.cpp
@@ -10457,7 +10497,8 @@ msgid "Per-level Counter"
msgstr "Contador Por Nivel"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Si esta activo el contador reinicia por cada grupo de nodos hijos"
#: editor/rename_dialog.cpp
@@ -10517,7 +10558,8 @@ msgid "Reset"
msgstr "Resetear"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Error de Expresión Regular"
#: editor/rename_dialog.cpp
@@ -12624,6 +12666,11 @@ msgstr ""
"Las GIProbes no están soportadas por el controlador de vídeo GLES2.\n"
"Usa un BakedLightmap en su lugar."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12937,6 +12984,16 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Sistema de Archivo e Importación"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Al exportar o distribuir, el ejecutable generado intentará conectarse a "
+#~ "la IP de este equipo para ser depurado."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "La escena actual nunca se guardó. Por favor, guárdela antes de ejecutar."
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index f2c72ce1be..6171c0e27d 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -542,6 +542,7 @@ msgid "Seconds"
msgstr "Segundos"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -720,7 +721,7 @@ msgstr "Coincidir Mayúsculas/Minúsculas"
msgid "Whole Words"
msgstr "Palabras Completas"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Reemplazar"
@@ -914,6 +915,11 @@ msgid "Signals"
msgstr "Señales"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrar tiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "¿Estás seguro/a que querés quitar todas las conexiones de esta señal?"
@@ -951,7 +957,7 @@ msgid "Recent:"
msgstr "Recientes:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Buscar:"
@@ -1133,6 +1139,9 @@ msgstr "Fundadores del Proyecto"
msgid "Lead Developer"
msgstr "Desarrollador Principal"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Gestor de Proyectos "
@@ -1154,6 +1163,16 @@ msgid "Gold Sponsors"
msgstr "Sponsor Oro"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Donantes Plata"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Donantes Bronce"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsors"
@@ -1630,16 +1649,17 @@ msgid "Scene Tree Editing"
msgstr "Edición de Árbol de Escenas"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Dock de Importación"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Dock de Nodos"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Docks de Sistema de Archivos e Importación"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistema de Archivos"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Dock de Importación"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1905,7 +1925,7 @@ msgstr "Directorios y Archivos:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Vista Previa:"
@@ -2793,24 +2813,28 @@ msgstr "Hacer Deploy con Depuración Remota"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Al exportar o hacer deploy, el ejecutable resultante tratara de conectarse a "
-"la IP de esta computadora de manera de ser depurado."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Deploy Pequeño con recursos en red"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Cuando esta opción está activa, exportar o hacer deploy producirá un "
"ejecutable mínimo.\n"
@@ -2824,9 +2848,10 @@ msgid "Visible Collision Shapes"
msgstr "Collision Shapes Visibles"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Los Collision shapes y nodos raycast (para 2D y 3D) serán visibles durante "
"la ejecución del juego cuando esta opción queda activada."
@@ -2836,23 +2861,26 @@ msgid "Visible Navigation"
msgstr "Navegación Visible"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Los meshes de navegación y los polígonos serán visibles durante la ejecución "
"del juego si esta opción queda activada."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizar Cambios de Escena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Cuando esta opción esté encendida, cualquier cambio hecho a la escena en el "
"editor será replicado en el juego en ejecución.\n"
@@ -2860,15 +2888,17 @@ msgstr ""
"sistema de archivos remoto."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizar Cambios en Scripts"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Cuando esta opción está activa, cualquier script que se guarde sera vuelto a "
"cargar en el juego en ejecución.\n"
@@ -2932,7 +2962,7 @@ msgstr "Ayuda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Buscar"
@@ -3352,9 +3382,11 @@ msgid "Add Key/Value Pair"
msgstr "Agregar Par Clave/Valor"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"No se encontró ningún preset de exportación ejecutable para esta "
"plataforma.\n"
@@ -5131,7 +5163,7 @@ msgid "Bake Lightmaps"
msgstr "Bake Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Vista Previa"
@@ -7782,7 +7814,8 @@ msgid "New Animation"
msgstr "Nueva Animación"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocidad (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9916,6 +9949,7 @@ msgstr ""
"existentes?\n"
"Podría demorar un rato."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestor de Proyectos"
@@ -10356,11 +10390,18 @@ msgid "Batch Rename"
msgstr "Renombrar en Masa"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Reemplazar: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefijo"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufijo"
#: editor/rename_dialog.cpp
@@ -10408,7 +10449,8 @@ msgid "Per-level Counter"
msgstr "Contador Por Nivel"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Si esta activo el contador reinicia por cada grupo de nodos hijos"
#: editor/rename_dialog.cpp
@@ -10468,7 +10510,8 @@ msgid "Reset"
msgstr "Resetear"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Error de Expresión Regular"
#: editor/rename_dialog.cpp
@@ -12570,6 +12613,11 @@ msgstr ""
"Las GIProbes no están soportadas por el controlador de video GLES2.\n"
"Usá un BakedLightmap en su lugar."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12878,6 +12926,16 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Docks de Sistema de Archivos e Importación"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Al exportar o hacer deploy, el ejecutable resultante tratara de "
+#~ "conectarse a la IP de esta computadora de manera de ser depurado."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "La escena actual nunca se guardó. Favor de guardarla antes de ejecutar."
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 504de558d5..a8692d1332 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -9,7 +9,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
+"PO-Revision-Date: 2020-09-01 10:38+0000\n"
"Last-Translator: StReef <streef.gtx@gmail.com>\n"
"Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/"
"godot/et/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.2.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -515,6 +515,7 @@ msgid "Seconds"
msgstr "Sekundid"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "K/S"
@@ -693,7 +694,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -799,7 +800,7 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Advanced"
-msgstr ""
+msgstr "Täpsem"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -882,6 +883,11 @@ msgid "Signals"
msgstr "Signaalid"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtreeri sõlmed"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -912,23 +918,23 @@ msgstr ""
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
msgid "Favorites:"
-msgstr ""
+msgstr "Lemmikud:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
-msgstr ""
+msgstr "Hiljutised:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
-msgstr ""
+msgstr "Otsi:"
#: 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 "Vasted:"
#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
#: editor/plugin_config_dialog.cpp
@@ -936,7 +942,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Description:"
-msgstr ""
+msgstr "Kirjeldus:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
@@ -1059,7 +1065,7 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
msgid "Delete"
-msgstr ""
+msgstr "Kustuta"
#: editor/dependency_editor.cpp
msgid "Owns"
@@ -1079,7 +1085,7 @@ msgstr ""
#: editor/editor_about.cpp
msgid "Thanks from the Godot community!"
-msgstr "Tänu Godot kogukonnale!"
+msgstr "Suur tänu Godot kogukonnalt!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
@@ -1093,6 +1099,9 @@ msgstr "Projekti asutajad"
msgid "Lead Developer"
msgstr "Juhtiv arendaja"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projekti juht "
@@ -1114,6 +1123,16 @@ msgid "Gold Sponsors"
msgstr "Kuldsponsorid"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Hõbennetajad"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Pronksannetajad"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Väikesponsorid"
@@ -1148,14 +1167,18 @@ msgid ""
"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
+"Godot mängumootor tugineb mitmetele kolmandate osapoolte tasuta ja avatud "
+"lähtekoodiga teekidele, mis kõik on kooskõlas MIT-litsentsi tingimustega. "
+"Järgnev on kõigi selliste kolmandate osapoolte komponentide täielik loetelu "
+"koos vastavate autoriõiguste avalduste ja litsentsitingimustega."
#: editor/editor_about.cpp
msgid "All Components"
-msgstr ""
+msgstr "Kõik komponendid"
#: editor/editor_about.cpp
msgid "Components"
-msgstr ""
+msgstr "Komponendid"
#: editor/editor_about.cpp
msgid "Licenses"
@@ -1204,7 +1227,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Speakers"
-msgstr ""
+msgstr "Heliväljundi"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
@@ -1269,7 +1292,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr ""
+msgstr "Duplikeeri"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -1584,15 +1607,16 @@ msgid "Scene Tree Editing"
msgstr "Stseenipuu redigeerimine"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
-msgstr ""
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Failikuvaja"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1858,7 +1882,7 @@ msgstr "Kataloogid ja failid:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Eelvaade:"
@@ -2287,15 +2311,15 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Quick Open..."
-msgstr ""
+msgstr "Ava kiiresti..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr ""
+msgstr "Ava kiiresti stseen..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr ""
+msgstr "Ava kiiresti skript..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2423,22 +2447,28 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr ""
+msgstr "Lisa-skripti ei olnud võimalik laadida teelt: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"Lisa-skripti ei olnud võimalik laadida teelt: '%s'. Tundub, et koodis on "
+"viga, palun kontrolli süntaksi."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
+"Lisa-skripti ei olnud võimalik laadida teelt: '%s'. Baastüüp ei ole "
+"EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
+"Lisa-skripti ei olnud võimalik laadida teelt: '%s'. Skript ei ole tööriista "
+"režiimis."
#: editor/editor_node.cpp
msgid ""
@@ -2609,7 +2639,7 @@ msgstr "Salvesta kõik stseenid"
#: editor/editor_node.cpp
msgid "Convert To..."
-msgstr ""
+msgstr "Teisenda..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
@@ -2689,22 +2719,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2713,8 +2747,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2723,32 +2757,34 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
-msgstr ""
+#, fuzzy
+msgid "Synchronize Scene Changes"
+msgstr "Pinna muutused"
#: 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
-msgstr ""
+#, fuzzy
+msgid "Synchronize Script Changes"
+msgstr "Varjutaja muutused"
#: 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2808,7 +2844,7 @@ msgstr "Abi"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Otsi"
@@ -2827,7 +2863,7 @@ msgstr "Teavita veast"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr "Saada dokumentatsioonide tagasisede"
+msgstr "Saada dokumentatsioonide tagasiside"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -2971,7 +3007,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Load Errors"
-msgstr ""
+msgstr "Laadimisvead"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
msgid "Select"
@@ -3027,36 +3063,36 @@ msgstr ""
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
-msgstr ""
+msgstr "Paigaldatud pistikprogrammid:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Update"
-msgstr ""
+msgstr "Uuenda"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Version:"
-msgstr ""
+msgstr "Versioon:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Author:"
-msgstr ""
+msgstr "Autor:"
#: editor/editor_plugin_settings.cpp
msgid "Status:"
-msgstr ""
+msgstr "Olek:"
#: editor/editor_plugin_settings.cpp
msgid "Edit:"
-msgstr ""
+msgstr "Muuda:"
#: editor/editor_profiler.cpp
msgid "Measure:"
-msgstr ""
+msgstr "Mõõda:"
#: editor/editor_profiler.cpp
msgid "Frame Time (sec)"
-msgstr ""
+msgstr "Kaadri aeg (sek)"
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
@@ -3064,7 +3100,7 @@ msgstr ""
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr ""
+msgstr "Kaadri %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
@@ -3080,15 +3116,15 @@ msgstr ""
#: editor/editor_profiler.cpp
msgid "Frame #:"
-msgstr ""
+msgstr "Kaader nr:"
#: editor/editor_profiler.cpp
msgid "Time"
-msgstr ""
+msgstr "Aeg"
#: editor/editor_profiler.cpp
msgid "Calls"
-msgstr ""
+msgstr "Kutsungid"
#: editor/editor_properties.cpp
msgid "Edit Text:"
@@ -3140,15 +3176,15 @@ msgstr ""
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr ""
+msgstr "Vali vaateaken"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
-msgstr ""
+msgstr "Uus skript"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
msgid "Extend Script"
-msgstr ""
+msgstr "Laienda skripti"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
@@ -3199,7 +3235,7 @@ msgstr ""
#: editor/editor_properties_array_dict.cpp
msgid "New Value:"
-msgstr ""
+msgstr "Uus väärtus:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
@@ -3208,7 +3244,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -3428,7 +3465,7 @@ msgstr ""
#: editor/export_template_manager.cpp
msgid "Current Version:"
-msgstr ""
+msgstr "Praegune versioon:"
#: editor/export_template_manager.cpp
msgid "Installed Versions:"
@@ -3540,7 +3577,7 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Add to Favorites"
-msgstr ""
+msgstr "Lisa lemmikutesse"
#: editor/filesystem_dock.cpp
msgid "Remove from Favorites"
@@ -3548,45 +3585,45 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
-msgstr ""
+msgstr "Redigeeri sõltuvusi..."
#: editor/filesystem_dock.cpp
msgid "View Owners..."
-msgstr ""
+msgstr "Kuva omanikud..."
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
-msgstr ""
+msgstr "Muuda nime..."
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
-msgstr ""
+msgstr "Duplikeeri..."
#: editor/filesystem_dock.cpp
msgid "Move To..."
-msgstr ""
+msgstr "Teisalda..."
#: editor/filesystem_dock.cpp
msgid "New Scene..."
-msgstr ""
+msgstr "Uus stseen..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
-msgstr ""
+msgstr "Uus skript..."
#: editor/filesystem_dock.cpp
msgid "New Resource..."
-msgstr ""
+msgstr "Uus ressurss..."
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Expand All"
-msgstr ""
+msgstr "Laienda kõik"
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Collapse All"
-msgstr ""
+msgstr "Ahenda kõik"
#: editor/filesystem_dock.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -3597,11 +3634,11 @@ msgstr "Nimeta ümber"
#: editor/filesystem_dock.cpp
msgid "Previous Folder/File"
-msgstr ""
+msgstr "Eelmine kaust/fail"
#: editor/filesystem_dock.cpp
msgid "Next Folder/File"
-msgstr ""
+msgstr "Järgmine kaust/fail"
#: editor/filesystem_dock.cpp
msgid "Re-Scan Filesystem"
@@ -3609,7 +3646,7 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Toggle Split Mode"
-msgstr ""
+msgstr "Lülita jagamisrežiim sisse/välja"
#: editor/filesystem_dock.cpp
msgid "Search files"
@@ -3639,7 +3676,7 @@ msgstr "Loo stseen"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr ""
+msgstr "Loo skript"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
msgid "Find in Files"
@@ -3954,7 +3991,7 @@ msgstr ""
#: editor/plugin_config_dialog.cpp
msgid "Edit a Plugin"
-msgstr ""
+msgstr "Pistikprogrammi muutmine"
#: editor/plugin_config_dialog.cpp
msgid "Create a Plugin"
@@ -3962,7 +3999,7 @@ msgstr ""
#: editor/plugin_config_dialog.cpp
msgid "Plugin Name:"
-msgstr ""
+msgstr "Pistikprogrammi nimi:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
@@ -3970,11 +4007,11 @@ msgstr ""
#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
msgid "Language:"
-msgstr ""
+msgstr "Keel:"
#: editor/plugin_config_dialog.cpp
msgid "Script Name:"
-msgstr ""
+msgstr "Skripti nimi:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
@@ -4214,7 +4251,7 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "Kustuta sõlm(ed)"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Toggle Filter On/Off"
@@ -4379,7 +4416,7 @@ msgstr "Animatsiooni tööriistad"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "Animatsioon"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Edit Transitions..."
@@ -4443,7 +4480,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Include Gizmos (3D)"
-msgstr ""
+msgstr "Kaasa vidinad (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pin AnimationPlayer"
@@ -4715,7 +4752,7 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "View Files"
-msgstr ""
+msgstr "Kuva failid"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
@@ -4875,7 +4912,7 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Plugins..."
-msgstr ""
+msgstr "Pistikprogrammid..."
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
msgid "Sort:"
@@ -4932,9 +4969,9 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
-msgstr ""
+msgstr "Eelvaade"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
@@ -5349,7 +5386,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View"
-msgstr ""
+msgstr "Kuva"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
@@ -5373,7 +5410,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Viewport"
-msgstr ""
+msgstr "Kuva vaateaken"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
@@ -6392,7 +6429,7 @@ msgstr ""
#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Type:"
-msgstr ""
+msgstr "Tüüp:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
@@ -6530,21 +6567,21 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Up"
-msgstr ""
+msgstr "Liiguta üles"
#: 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 "Liiguta allapoole"
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
-msgstr ""
+msgstr "Järgmine skript"
#: editor/plugins/script_editor_plugin.cpp
msgid "Previous script"
-msgstr ""
+msgstr "Eelmine skript"
#: editor/plugins/script_editor_plugin.cpp
msgid "File"
@@ -6617,12 +6654,12 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
-msgstr ""
+msgstr "Paus"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr ""
+msgstr "Jätka"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
@@ -7095,7 +7132,7 @@ msgstr "Kuva keskkond"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Gizmos"
-msgstr ""
+msgstr "Kuva vidinad"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
@@ -7262,44 +7299,44 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
-msgstr ""
+msgstr "1 vaateaken"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports"
-msgstr ""
+msgstr "2 vaateakent"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
-msgstr ""
+msgstr "2 vaateakent (alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
-msgstr ""
+msgstr "3 vaateakent"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
-msgstr ""
+msgstr "3 vaateakent (alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
-msgstr ""
+msgstr "4 vaateakent"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
-msgstr ""
+msgstr "Vidinad"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Origin"
-msgstr ""
+msgstr "Kuva lähtekoht"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Grid"
-msgstr ""
+msgstr "Kuva ruudustik"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Settings..."
-msgstr ""
+msgstr "Sätted..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7319,7 +7356,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
-msgstr ""
+msgstr "Vaateakna sätted"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
@@ -7475,7 +7512,7 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Unable to load images"
-msgstr ""
+msgstr "Pilte ei saa laadida"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
@@ -7514,7 +7551,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -7748,7 +7785,7 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
-msgstr ""
+msgstr "Andmetüüp:"
#: editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
@@ -7876,7 +7913,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from Scene"
-msgstr ""
+msgstr "Liida stseenist"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Single Tile"
@@ -8247,7 +8284,7 @@ msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
-msgstr ""
+msgstr "Olek"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "View file diffs before committing them to the latest version"
@@ -9119,7 +9156,7 @@ msgstr ""
#: editor/project_export.cpp editor/project_settings_editor.cpp
msgid "Add..."
-msgstr ""
+msgstr "Lisa..."
#: editor/project_export.cpp
msgid ""
@@ -9193,7 +9230,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Script"
-msgstr ""
+msgstr "Skript"
#: editor/project_export.cpp
msgid "Script Export Mode:"
@@ -9492,6 +9529,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "projektihaldur"
@@ -9807,15 +9845,15 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Localization"
-msgstr ""
+msgstr "Tõlked"
#: editor/project_settings_editor.cpp
msgid "Translations"
-msgstr ""
+msgstr "Tõlked"
#: editor/project_settings_editor.cpp
msgid "Translations:"
-msgstr ""
+msgstr "Tõlked:"
#: editor/project_settings_editor.cpp
msgid "Remaps"
@@ -9859,7 +9897,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr ""
+msgstr "Pistikprogrammid"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -9922,11 +9960,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9935,7 +9977,7 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Advanced Options"
-msgstr ""
+msgstr "Täpsemad sätted"
#: editor/rename_dialog.cpp
msgid "Substitute"
@@ -9972,7 +10014,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10030,7 +10072,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10218,7 +10260,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
-msgstr ""
+msgstr "Manusta skript"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
@@ -10244,7 +10286,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Sub-Resources"
-msgstr ""
+msgstr "Alamressursid"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance"
@@ -10260,7 +10302,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Open Documentation"
-msgstr ""
+msgstr "Ava dokumentatsioon"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10275,11 +10317,11 @@ msgstr "Lisa alamsõlm"
#: editor/scene_tree_dock.cpp
msgid "Expand/Collapse All"
-msgstr ""
+msgstr "Laienda/ahenda kõik"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
-msgstr ""
+msgstr "Muuda tüüpi"
#: editor/scene_tree_dock.cpp
msgid "Reparent to New Node"
@@ -10287,7 +10329,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
-msgstr ""
+msgstr "Tee stseeni juurikaks"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -10295,11 +10337,11 @@ msgstr ""
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Save Branch as Scene"
-msgstr ""
+msgstr "Salvesta filiaal stseenina"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Copy Node Path"
-msgstr ""
+msgstr "Kopeeri sõlme tee"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
@@ -10477,7 +10519,7 @@ msgstr ""
#: editor/script_create_dialog.cpp
msgid "Open Script"
-msgstr ""
+msgstr "Ava skript"
#: editor/script_create_dialog.cpp
msgid "File exists, it will be reused."
@@ -10583,7 +10625,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Errors"
-msgstr ""
+msgstr "Vead"
#: editor/script_editor_debugger.cpp
msgid "Child process connected."
@@ -10591,11 +10633,11 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr ""
+msgstr "Kopeeri viga"
#: editor/script_editor_debugger.cpp
msgid "Video RAM"
-msgstr ""
+msgstr "Videomälu"
#: editor/script_editor_debugger.cpp
msgid "Skip Breakpoints"
@@ -10611,7 +10653,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Stack Frames"
-msgstr ""
+msgstr "Virnakaadrid"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
@@ -10623,15 +10665,15 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Monitor"
-msgstr ""
+msgstr "Jälgija"
#: editor/script_editor_debugger.cpp
msgid "Value"
-msgstr ""
+msgstr "Väärtus"
#: editor/script_editor_debugger.cpp
msgid "Monitors"
-msgstr ""
+msgstr "Jälgijad"
#: editor/script_editor_debugger.cpp
msgid "Pick one or more items from the list to display the graph."
@@ -10639,7 +10681,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "List of Video Memory Usage by Resource:"
-msgstr ""
+msgstr "Videomälu kasutamise loetelu ressursside kaupa:"
#: editor/script_editor_debugger.cpp
msgid "Total:"
@@ -10651,7 +10693,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Resource Path"
-msgstr ""
+msgstr "Ressursi tee"
#: editor/script_editor_debugger.cpp
msgid "Type"
@@ -10659,15 +10701,15 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Format"
-msgstr ""
+msgstr "Formaat"
#: editor/script_editor_debugger.cpp
msgid "Usage"
-msgstr ""
+msgstr "Kasutus"
#: editor/script_editor_debugger.cpp
msgid "Misc"
-msgstr ""
+msgstr "Muud"
#: editor/script_editor_debugger.cpp
msgid "Clicked Control:"
@@ -10686,8 +10728,9 @@ msgid "Set From Tree"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Ekspordi mõõtmed/meetmed CSV-vormingus"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10831,11 +10874,11 @@ msgstr ""
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
-msgstr ""
+msgstr "Teek"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Libraries: "
-msgstr ""
+msgstr "Teegid: "
#: modules/gdnative/register_types.cpp
msgid "GDNative"
@@ -11960,6 +12003,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 906a258f32..07923f26fb 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -507,6 +507,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -685,7 +686,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -874,6 +875,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -911,7 +916,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1090,6 +1095,9 @@ msgstr "Proiektuaren sortzaileak"
msgid "Lead Developer"
msgstr "Garatzaile nagusia"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Proiektu-kudeatzailea "
@@ -1111,6 +1119,16 @@ msgid "Gold Sponsors"
msgstr "Urrezko babesleak"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Zilarrezko emaileak"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Brontzezko emaileak"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini babesleak"
@@ -1574,15 +1592,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1845,7 +1863,7 @@ msgstr "Direktorioak eta fitxategiak:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Aurrebista:"
@@ -2671,22 +2689,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2695,8 +2717,8 @@ msgstr "Talka formak ikusgai"
#: 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2705,32 +2727,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2790,7 +2812,7 @@ msgstr "Laguntza"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Bilatu"
@@ -3190,7 +3212,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4920,7 +4943,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7502,7 +7525,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9481,6 +9504,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9913,11 +9937,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9963,7 +9991,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10021,7 +10049,8 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Adierazpen erregularraren errorea"
#: editor/rename_dialog.cpp
@@ -11953,6 +11982,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 02ed65131f..93124ec30c 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -49,28 +49,27 @@ msgstr ""
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
-"Content-Transfer-Encoding: 8-bit\\n"
+"Content-Transfer-Encoding: 8-bit\\n"\n
"""
def _write_message(msgctx, msg, msg_plural, location):
global main_po
- main_po += "\n#: " + location + "\n"
+ main_po += "#: " + location + "\n"
if msgctx != "":
main_po += 'msgctxt "' + msgctx + '"\n'
main_po += 'msgid "' + msg + '"\n'
if msg_plural != "":
main_po += 'msgid_plural "' + msg_plural + '"\n'
main_po += 'msgstr[0] ""\n'
- main_po += 'msgstr[1] ""\n'
+ main_po += 'msgstr[1] ""\n\n'
else:
- main_po += 'msgstr ""\n'
+ main_po += 'msgstr ""\n\n'
def _add_additional_location(msgctx, msg, location):
global main_po
- # Add additional location to previous occurrence
- msg_pos = -1
+ # Add additional location to previous occurrence.
if msgctx != "":
msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"')
else:
@@ -81,18 +80,137 @@ def _add_additional_location(msgctx, msg, location):
main_po = main_po[:msg_pos] + " " + location + main_po[msg_pos:]
+def _write_translator_comment(msgctx, msg, translator_comment):
+ if translator_comment == "":
+ return
+
+ global main_po
+ if msgctx != "":
+ msg_pos = main_po.find('\nmsgctxt "' + msgctx + '"\nmsgid "' + msg + '"')
+ else:
+ msg_pos = main_po.find('\nmsgid "' + msg + '"')
+
+ # If it's a new message, just append comment to the end of PO file.
+ if msg_pos == -1:
+ main_po += _format_translator_comment(translator_comment, True)
+ return
+
+ # Find position just before location. Translator comment will be added there.
+ translator_comment_pos = main_po.rfind("\n\n#", 0, msg_pos) + 2
+ if translator_comment_pos - 2 == -1:
+ print("translator_comment_pos not found")
+ return
+
+ # Check if a previous translator comment already exists. If so, merge them together.
+ if main_po.find("TRANSLATORS:", translator_comment_pos, msg_pos) != -1:
+ translator_comment_pos = main_po.find("\n#:", translator_comment_pos, msg_pos) + 1
+ if translator_comment_pos == 0:
+ print('translator_comment_pos after "TRANSLATORS:" not found')
+ return
+ main_po = (
+ main_po[:translator_comment_pos]
+ + _format_translator_comment(translator_comment, False)
+ + main_po[translator_comment_pos:]
+ )
+ return
+
+ main_po = (
+ main_po[:translator_comment_pos]
+ + _format_translator_comment(translator_comment, True)
+ + main_po[translator_comment_pos:]
+ )
+
+
+def _format_translator_comment(comment, new):
+ if not comment:
+ return ""
+
+ comment_lines = comment.split("\n")
+
+ formatted_comment = ""
+ if not new:
+ for comment in comment_lines:
+ formatted_comment += "#. " + comment.strip() + "\n"
+ return formatted_comment
+
+ formatted_comment = "#. TRANSLATORS: "
+ for i in range(len(comment_lines)):
+ if i == 0:
+ formatted_comment += comment_lines[i].strip() + "\n"
+ else:
+ formatted_comment += "#. " + comment_lines[i].strip() + "\n"
+ return formatted_comment
+
+
+def _is_block_translator_comment(translator_line):
+ line = translator_line.strip()
+ if line.find("//") == 0:
+ return False
+ else:
+ return True
+
+
+def _extract_translator_comment(line, is_block_translator_comment):
+ line = line.strip()
+ reached_end = False
+ extracted_comment = ""
+
+ start = line.find("TRANSLATORS:")
+ if start == -1:
+ start = 0
+ else:
+ start += len("TRANSLATORS:")
+
+ if is_block_translator_comment:
+ # If '*/' is found, then it's the end.
+ if line.rfind("*/") != -1:
+ extracted_comment = line[start : line.rfind("*/")]
+ reached_end = True
+ else:
+ extracted_comment = line[start:]
+ else:
+ # If beginning is not '//', then it's the end.
+ if line.find("//") != 0:
+ reached_end = True
+ else:
+ start = 2 if start == 0 else start
+ extracted_comment = line[start:]
+
+ return (not reached_end, extracted_comment)
+
+
def process_file(f, fname):
global main_po, unique_str, unique_loc
+ patterns = ['RTR("', 'TTR("', 'TTRC("', 'TTRN("', 'RTRN("']
+
l = f.readline()
lc = 1
+ reading_translator_comment = False
+ is_block_translator_comment = False
+ translator_comment = ""
+
while l:
- patterns = ['RTR("', 'TTR("', 'TTRC("', 'TTRN("', 'RTRN("']
+ # Detect translator comments.
+ if not reading_translator_comment and l.find("TRANSLATORS:") != -1:
+ reading_translator_comment = True
+ is_block_translator_comment = _is_block_translator_comment(l)
+ translator_comment = ""
+
+ # Gather translator comments. It will be gathered for the next translation function.
+ if reading_translator_comment:
+ reading_translator_comment, extracted_comment = _extract_translator_comment(l, is_block_translator_comment)
+ if extracted_comment != "":
+ translator_comment += extracted_comment + "\n"
+ if not reading_translator_comment:
+ translator_comment = translator_comment[:-1] # Remove extra \n at the end.
+
idx = 0
pos = 0
- while pos >= 0:
+
+ while not reading_translator_comment and pos >= 0:
# Loop until a pattern is found. If not, next line.
pos = l.find(patterns[idx], pos)
if pos == -1:
@@ -140,6 +258,10 @@ def process_file(f, fname):
if line_nb:
location += ":" + str(lc)
+ # Write translator comment.
+ _write_translator_comment(msgctx, msg, translator_comment)
+ translator_comment = ""
+
if msgctx != "":
# If it's a new context or a new message within an existing context, then write new msgid.
# Else add location to existing msgid.
@@ -160,6 +282,7 @@ def process_file(f, fname):
elif not location in unique_loc[msg]:
_add_additional_location(msgctx, msg, location)
unique_loc[msg].append(location)
+
l = f.readline()
lc += 1
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index dc7ae9ec69..2d17cc0abb 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -14,12 +14,13 @@
# Focus <saeeddashticlash@gmail.com>, 2019, 2020.
# mohamad por <mohamad24xx@gmail.com>, 2020.
# Tetra Homer <tetrahomer@gmail.com>, 2020.
+# Farshad Faemiyi <ffaemiyi@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-21 13:41+0000\n"
-"Last-Translator: Tetra Homer <tetrahomer@gmail.com>\n"
+"PO-Revision-Date: 2020-09-16 18:09+0000\n"
+"Last-Translator: Farshad Faemiyi <ffaemiyi@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -27,7 +28,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -416,7 +417,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "آهنگ های انیمیشن فقط می توانند به گره های انیمش پلیر اشاره کنند."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
@@ -452,7 +453,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"
@@ -534,6 +535,7 @@ msgid "Seconds"
msgstr "ثانیه ها"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "لحظه بر ثانیه"
@@ -553,7 +555,7 @@ msgstr "خصوصیات انیمیشن."
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr ""
+msgstr "کپی میسر ها"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -593,7 +595,7 @@ msgstr "انیمیشن را پاکسازی کن"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "گره متحرک را انتخاب کنید:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
@@ -712,7 +714,7 @@ msgstr "بین حروف کوچک و بزرگ لاتین تمایز قائل شو
msgid "Whole Words"
msgstr "عین کلمات (بدون هیچ کم و کاستی)"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "جایگزینی"
@@ -751,11 +753,11 @@ msgstr "باز‌نشانی مقیاس"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr ""
+msgstr "هشدارها"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr ""
+msgstr "شماره های خط و ستون."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
@@ -823,7 +825,7 @@ msgstr "پیشرفته"
#: editor/connections_dialog.cpp
msgid "Deferred"
-msgstr "معوق"
+msgstr "به تعویق افتاده"
#: editor/connections_dialog.cpp
msgid ""
@@ -896,12 +898,18 @@ msgstr "ویرایش اتصال:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
msgstr ""
+"آیا مطمئن هستید که می خواهید همه اتصالات را از سیگنال \"٪ s\" حذف کنید؟"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
msgstr "سیگنال‌ها"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "صافی کردن گره‌ها"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -939,7 +947,7 @@ msgid "Recent:"
msgstr "اخیر:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "جستجو:"
@@ -994,7 +1002,7 @@ msgstr "منبع"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
-msgstr "مسیر"
+msgstr "آدرس"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
@@ -1086,7 +1094,7 @@ msgstr "پوینده‌ی منبع جدا افتاده"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
msgid "Delete"
-msgstr "حذف کن"
+msgstr "پاک"
#: editor/dependency_editor.cpp
msgid "Owns"
@@ -1120,6 +1128,9 @@ msgstr "بنیان‌گذاران پروژه"
msgid "Lead Developer"
msgstr "توسعه‌دهنده‌ی اصلی"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "مدیر پروژه "
@@ -1134,15 +1145,25 @@ msgstr "مؤلفان"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr "حامیان پلاتینیُم (درجه ۱)"
+msgstr "حامیان پلاتین"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
msgstr "حامیان طلایی (درجه ۲)"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "اهداکنندگان نقره‌ای"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "اهداکنندگان برنزی"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
-msgstr "اسپانسر‌های کوچک"
+msgstr "حامیان مالی کوچک"
#: editor/editor_about.cpp
msgid "Gold Donors"
@@ -1282,24 +1303,25 @@ msgstr "برای چینش مجدد، بکشید و رها کنید."
#: editor/editor_audio_buses.cpp
msgid "Solo"
-msgstr ""
+msgstr "انفرادی"
#: editor/editor_audio_buses.cpp
msgid "Mute"
-msgstr ""
+msgstr "بدون صدا"
#: editor/editor_audio_buses.cpp
msgid "Bypass"
-msgstr ""
+msgstr "‌گذرگاه فرعی"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Bus options"
-msgstr ""
+msgstr "گزینه های اتوبوس"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr ""
+msgstr "تکثیر کردن"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -1315,11 +1337,12 @@ msgstr "صدا"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "افزودن کانل صوتی"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "استاد اتوبوس قابل حذف نیست!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -1436,8 +1459,9 @@ msgid "Rename Autoload"
msgstr "بارگذاری خودکار را تغییر نام بده"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Toggle AutoLoad Globals"
-msgstr ""
+msgstr "تغییر حالت اتماتیک لود عمومی"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -1478,11 +1502,11 @@ msgstr "نام گره:"
#: editor/editor_profiler.cpp editor/project_manager.cpp
#: editor/settings_config_dialog.cpp
msgid "Name"
-msgstr ""
+msgstr "نام"
#: editor/editor_autoload_settings.cpp
msgid "Singleton"
-msgstr ""
+msgstr "سینگلتون"
#: editor/editor_data.cpp editor/inspector_dock.cpp
msgid "Paste Params"
@@ -1540,15 +1564,15 @@ msgstr ""
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "ذخیره فایل:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "هیچ الگوی صادراتی در مسیر مورد انتظار یافت نشد:"
#: editor/editor_export.cpp
msgid "Packing"
-msgstr ""
+msgstr "بسته بندی"
#: editor/editor_export.cpp
msgid ""
@@ -1607,16 +1631,17 @@ 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 "فایل‌سیستم و وارد‌کردن لنگرگاه"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "سامانه پرونده"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "وارد کردن لنگرگاه"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1758,7 +1783,7 @@ msgstr "گشودن در مدیر پرونده"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
msgid "Show in File Manager"
-msgstr "نمایش در مدیر پرونده"
+msgstr "نمایش فایل داخلی مرجع"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
@@ -1878,7 +1903,7 @@ msgstr "پوشه‌ها و پرونده‌ها:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2703,22 +2728,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2727,8 +2756,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2737,32 +2766,33 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
-msgstr ""
+#, fuzzy
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2829,7 +2859,7 @@ msgstr "راهنما"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "جستجو"
@@ -3246,7 +3276,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -3466,7 +3497,7 @@ msgstr "خطای اتصال"
#: editor/export_template_manager.cpp
msgid "SSL Handshake Error"
-msgstr "دست دادن خطای اس اس ال"
+msgstr "خطای اس اس ال اتفاق افتاد است"
#: editor/export_template_manager.cpp
#, fuzzy
@@ -5094,7 +5125,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7822,7 +7853,7 @@ msgid "New Animation"
msgstr "تغییر نام انیمیشن"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9931,6 +9962,7 @@ msgstr ""
"شما درخواست بررسی پوشه های s٪‌ برای پیدا کردن پروژه های گودات را داده اید. "
"آیا انجام این عمل را تایید می کنید؟‌"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "مدیر پروژه"
@@ -10225,7 +10257,7 @@ msgstr "تنظیمات پروژه (پروژه.گودات)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr "کلی"
+msgstr "عمومی"
#: editor/project_settings_editor.cpp
msgid "Override For..."
@@ -10383,11 +10415,16 @@ msgid "Batch Rename"
msgstr "تغییر نام"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "جایگزینی"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10437,7 +10474,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10499,7 +10536,7 @@ msgstr "بازنشانی بزرگنمایی"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "انتقال را در انیمیشن تغییر بده"
#: editor/rename_dialog.cpp
@@ -12612,6 +12649,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12892,6 +12934,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "ثوابت قابل تغییر نیستند."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "فایل‌سیستم و وارد‌کردن لنگرگاه"
+
#~ msgid "Not in resource path."
#~ msgstr "در مسیرِ منبع نیست."
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 124ae4f2e0..93bfde1e50 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-05 16:58+0000\n"
+"PO-Revision-Date: 2020-09-05 09:37+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -24,7 +24,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -529,6 +529,7 @@ msgid "Seconds"
msgstr "Sekunnit"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -707,7 +708,7 @@ msgstr "Huomioi kirjainkoko"
msgid "Whole Words"
msgstr "Kokonaisia sanoja"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Korvaa"
@@ -899,6 +900,11 @@ msgid "Signals"
msgstr "Signaalit"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Suodata laattoja"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Oletko varma, että haluat poistaa kaikki kytkennät tältä signaalilta?"
@@ -936,7 +942,7 @@ msgid "Recent:"
msgstr "Viimeaikaiset:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Hae:"
@@ -1117,6 +1123,9 @@ msgstr "Projektin perustajat"
msgid "Lead Developer"
msgstr "Pääkehittäjä"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projektipäällikkö "
@@ -1138,6 +1147,14 @@ msgid "Gold Sponsors"
msgstr "Kultasponsorit"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Hopeasponsorit"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Pronssisponsorit"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Minisponsorit"
@@ -1616,16 +1633,17 @@ msgid "Scene Tree Editing"
msgstr "Skenepuun muokkaus"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Tuontitelakka"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Solmutelakka"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Tiedostojärjestelmä- ja tuontitelakat"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Tiedostojärjestelmä"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Tuontitelakka"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1891,7 +1909,7 @@ msgstr "Hakemistot ja tiedostot:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Esikatselu:"
@@ -2762,24 +2780,28 @@ msgstr "Julkaise etätestauksen kanssa"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Vietäessä tai julkaistaessa, käynnistettävä ohjelma yrittää ottaa yhteyden "
-"tämän tietokoneen IP-osoitteeseen testaamista varten."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Kevyt käyttöönotto verkkolevyn avulla"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Kun tämä on valittuna, vienti tai julkaisu tuottaa pienimmän mahdollisen "
"käynnistystiedoston.\n"
@@ -2793,9 +2815,10 @@ msgid "Visible Collision Shapes"
msgstr "Näytä törmäysmuodot"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Törmäysmuodot ja raycast-solmut (2D ja 3D) ovat näkyvillä peliä ajettaessa "
"tämän ollessa valittuna."
@@ -2805,38 +2828,43 @@ msgid "Visible Navigation"
msgstr "Näkyvä navigaatio"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigointiverkot ja niiden polygonit ovat näkyvillä peliä ajettaessa tämän "
"ollessa valittuna."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synkronoi skenen muutokset"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Tämän ollessa valittuna, kaikki skeneen tehdyt muutokset toteutetaan myös "
"käynnissä olevassa pelissä.\n"
"Mikäli peliä ajetaan etälaitteella, on tehokkaampaa käyttää verkkolevyä."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synkronoi skriptin muutokset"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Jos tämä on valittu, kaikki tallennetut skriptit ladataan uudelleen pelin "
"käynnistyessä.\n"
@@ -2899,7 +2927,7 @@ msgstr "Ohje"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Hae"
@@ -3317,9 +3345,11 @@ msgid "Add Key/Value Pair"
msgstr "Lisää avain/arvopari"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Käynnistettävää vientipohjaa ei löytynyt tälle alustalle.\n"
"Lisää sellainen vientivalikosta."
@@ -5089,7 +5119,7 @@ msgid "Bake Lightmaps"
msgstr "Kehitä Lightmapit"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Esikatselu"
@@ -7737,7 +7767,8 @@ msgid "New Animation"
msgstr "Uusi animaatio"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Nopeus (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9862,6 +9893,7 @@ msgstr ""
"Haluatko varmasti etsiä %s kansiosta olemassa olevia Godot-projekteja?\n"
"Tämä saattaa kestää hetken."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projektinhallinta"
@@ -10301,11 +10333,18 @@ msgid "Batch Rename"
msgstr "Niputettu uudelleennimeäminen"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Korvaa: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Etuliite"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Pääte"
#: editor/rename_dialog.cpp
@@ -10353,7 +10392,8 @@ msgid "Per-level Counter"
msgstr "Per taso -laskuri"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Jos asetettu, laskuri alkaa alusta jokaiselle alisolmujen ryhmälle"
#: editor/rename_dialog.cpp
@@ -10413,7 +10453,8 @@ msgid "Reset"
msgstr "Palauta"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Säännöllisen lausekkeen virhe"
#: editor/rename_dialog.cpp
@@ -12498,6 +12539,11 @@ msgstr ""
"GIProbe ei ole tuettu GLES2 näyttöajurissa.\n"
"Käytä sen sijaan BakedLightmap resurssia."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12805,6 +12851,16 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa."
msgid "Constants cannot be modified."
msgstr "Vakioita ei voi muokata."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Tiedostojärjestelmä- ja tuontitelakat"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Vietäessä tai julkaistaessa, käynnistettävä ohjelma yrittää ottaa "
+#~ "yhteyden tämän tietokoneen IP-osoitteeseen testaamista varten."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Nykyistä skeneä ei ole vielä tallennettu. Tallenna se ennen suorittamista."
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 490d9d92ec..de981e7625 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -5,11 +5,12 @@
# Marco Santos <enum.scima@gmail.com>, 2019.
# Amado Wilkins <epicalert68@gmail.com>, 2019.
# Bakainkorp <Ryan.Bautista86@myhunter.cuny.edu>, 2019.
+# Jethro Parker <lionbearjet@hotmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-12-21 08:37+0000\n"
-"Last-Translator: Bakainkorp <Ryan.Bautista86@myhunter.cuny.edu>\n"
+"PO-Revision-Date: 2020-08-14 03:56+0000\n"
+"Last-Translator: Jethro Parker <lionbearjet@hotmail.com>\n"
"Language-Team: Filipino <https://hosted.weblate.org/projects/godot-engine/"
"godot/fil/>\n"
"Language: fil\n"
@@ -17,7 +18,7 @@ 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.10\n"
+"X-Generator: Weblate 4.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -28,7 +29,7 @@ msgstr ""
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Nanghihingi ng string na may habang 1 (character)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -185,12 +186,12 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr ""
+msgstr "Ibahin ang haba ng Animation"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Ibahin ang ulit ng Animation"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -218,44 +219,44 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr ""
+msgstr "Haba ng animation (frames)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr ""
+msgstr "Haba ng animation (segundo)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
-msgstr ""
+msgstr "Magdagdag ng Track"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
-msgstr ""
+msgstr "Pagulit ng Animation"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Functions:"
-msgstr ""
+msgstr "Functions:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr ""
+msgstr "Mga clip ng tunog:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "Mga clip ng Anim:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr ""
+msgstr "Ibahin ang landas ng Track"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr ""
+msgstr "Ilipat sa on/off ang track na ito."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr ""
+msgstr "Baguhin ang Mode (Kung paano na-set ang property)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -514,6 +515,7 @@ msgid "Seconds"
msgstr "Segundo"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -693,7 +695,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Palitan"
@@ -882,6 +884,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -919,7 +925,7 @@ msgid "Recent:"
msgstr "Kamakailan:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Paghahanap:"
@@ -1093,6 +1099,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1114,6 +1123,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1577,15 +1594,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1848,7 +1865,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -1893,7 +1910,7 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Description"
-msgstr ""
+msgstr "Paglalarawan"
#: editor/editor_help.cpp
msgid "Online Tutorials"
@@ -2674,22 +2691,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2698,8 +2719,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2708,32 +2729,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2793,7 +2814,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -2816,11 +2837,11 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr ""
+msgstr "Komunidad"
#: editor/editor_node.cpp
msgid "About"
-msgstr ""
+msgstr "Tungkol"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -3195,7 +3216,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4920,7 +4942,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7506,7 +7528,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9485,6 +9507,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9915,11 +9938,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Palitan"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9965,7 +9993,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10023,7 +10051,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11957,6 +11985,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 9bb04cb2b0..c39d4c7e0c 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -79,8 +79,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-01 11:14+0000\n"
-"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n"
+"PO-Revision-Date: 2020-09-08 13:44+0200\n"
+"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -88,7 +88,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Poedit 2.4.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -136,7 +136,7 @@ msgstr "Lors de l’appel à '%s' :"
#: core/ustring.cpp
msgid "B"
-msgstr "Octet"
+msgstr "o"
#: core/ustring.cpp
msgid "KiB"
@@ -606,6 +606,7 @@ msgid "Seconds"
msgstr "Secondes"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "IPS"
@@ -784,7 +785,7 @@ msgstr "Sensible à la casse"
msgid "Whole Words"
msgstr "Mots entiers"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Remplacer"
@@ -977,6 +978,11 @@ msgid "Signals"
msgstr "Signaux"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrer les tuiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Voulez-vous vraiment supprimer toutes les connexions de ce signal ?"
@@ -1014,7 +1020,7 @@ msgid "Recent:"
msgstr "Récents :"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Rechercher :"
@@ -1196,9 +1202,12 @@ msgstr "Fondateurs du projet"
msgid "Lead Developer"
msgstr "Développeur principal"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Gestionnaire de projets "
+msgstr "Chef de projet "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1217,6 +1226,14 @@ msgid "Gold Sponsors"
msgstr "Sponsors Or"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Sponsors Argent"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Sponsors Bronze"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsors"
@@ -1694,16 +1711,17 @@ msgid "Scene Tree Editing"
msgstr "Édition de l'arbre de scène"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Dock d'importation"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Dock nœud"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Module d'importation et système de fichiers"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Système de fichiers"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Dock d'importation"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1968,7 +1986,7 @@ msgstr "Répertoires et fichiers :"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Aperçu :"
@@ -2861,24 +2879,28 @@ msgstr "Déployer avec le débogage distant"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Lors de l'exportation ou du déploiement, l'exécutable produit tentera de se "
-"connecter à l'adresse IP de cet ordinateur afin de procéder au débogage."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Déploiement minime avec système de fichier réseau"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Lorsque cette option est activée, l'exportation ou le déploiement produira "
"un exécutable minimal.\n"
@@ -2893,9 +2915,10 @@ msgid "Visible Collision Shapes"
msgstr "Formes de collision visibles"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Les formes de collision et les nœuds de raycast (pour 2D et 3D) seront "
"visibles en jeu si cette option est activée."
@@ -2905,23 +2928,26 @@ msgid "Visible Navigation"
msgstr "Navigation visible"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Les maillages et polygones de navigation seront visibles en jeu si cette "
"option est activée."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synchroniser les modifications des scènes"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Lorsque cette option est activée, toutes les modifications apportées à la "
"scène dans l'éditeur seront reproduites en jeu.\n"
@@ -2929,15 +2955,17 @@ msgstr ""
"plus efficace avec le système de fichiers réseau."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synchroniser les modifications des scripts"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Lorsque cette option est activée, tout script enregistré sera de nouveau "
"chargé pendant le déroulement du jeu.\n"
@@ -3002,7 +3030,7 @@ msgstr "Aide"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Rechercher"
@@ -3422,9 +3450,11 @@ msgid "Add Key/Value Pair"
msgstr "Ajouter une paire clé/valeur"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Aucun préréglage d'exportation exécutable trouvé pour cette plate-forme. \n"
"Ajoutez un préréglage exécutable dans le menu d'exportation."
@@ -5207,7 +5237,7 @@ msgid "Bake Lightmaps"
msgstr "Précalculer les lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Aperçu"
@@ -7876,7 +7906,8 @@ msgid "New Animation"
msgstr "Nouvelle animation"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Vitesse (IPS) :"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8580,7 +8611,7 @@ msgstr "Système de contrôle de version"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Initialize"
-msgstr "initialiser"
+msgstr "Initialiser"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
@@ -10017,6 +10048,7 @@ msgstr ""
"Godot existants ?\n"
"Cela pourrait prendre un moment."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestionnaire de projets"
@@ -10457,11 +10489,18 @@ msgid "Batch Rename"
msgstr "Renommer par lot"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Remplacer : "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Préfixe"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Suffixe"
#: editor/rename_dialog.cpp
@@ -10509,7 +10548,8 @@ msgid "Per-level Counter"
msgstr "Compteur par niveau"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Si défini, le compteur redémarre pour chaque groupe de nœuds enfant"
#: editor/rename_dialog.cpp
@@ -10569,7 +10609,8 @@ msgid "Reset"
msgstr "Réinitialiser"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Erreur dans l'expression régulière"
#: editor/rename_dialog.cpp
@@ -12683,6 +12724,11 @@ msgstr ""
"Les GIProps ne sont pas supporter par le pilote de vidéos GLES2.\n"
"A la place utilisez une BakedLightMap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13000,6 +13046,17 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex."
msgid "Constants cannot be modified."
msgstr "Les constantes ne peuvent être modifiées."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Module d'importation et système de fichiers"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Lors de l'exportation ou du déploiement, l'exécutable produit tentera de "
+#~ "se connecter à l'adresse IP de cet ordinateur afin de procéder au "
+#~ "débogage."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "La scène actuelle n'a jamais été sauvegardée, veuillez la sauvegarder "
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index a496566c2e..d727d2a1fa 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -508,6 +508,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -686,7 +687,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -875,6 +876,11 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Scagairí..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -912,7 +918,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Cuardach:"
@@ -1086,6 +1092,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1107,6 +1116,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1571,15 +1588,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1842,7 +1859,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2669,22 +2686,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2693,8 +2714,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2703,32 +2724,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2788,7 +2809,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3188,7 +3209,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4917,7 +4939,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7500,7 +7522,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9481,6 +9503,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9911,11 +9934,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9961,7 +9988,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10019,7 +10046,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11955,6 +11982,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 0f9a19c842..3a508c0d6d 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -15,11 +15,12 @@
# Anonymous <noreply@weblate.org>, 2020.
# Daniel Kariv <danielkariv98@gmail.com>, 2020.
# Ziv D <wizdavid@gmail.com>, 2020.
+# yariv benj <yariv4400@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
+"PO-Revision-Date: 2020-09-24 12:43+0000\n"
"Last-Translator: Ziv D <wizdavid@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/"
"godot/he/>\n"
@@ -29,16 +30,16 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
"n % 10 == 0) ? 2 : 3));\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-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_*‎."
+msgstr "סוג משתנה לא חוקי לפונקציית convert()‎, יש להשתמש בקבועי TYPE_*‎."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "צפויה מחרוזת באורך 1 (תו)."
+msgstr "היתה צפויה מחרוזת באורך 1 (תו)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -52,7 +53,7 @@ msgstr "קלט שגוי %I (לא הועבר) בתוך הביטוי"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "לא ניתן להשתמש ב־self כיוון שהמופע הוא אפס (null - לא הועבר)"
+msgstr "'self' לא ניתן לשימוש כי המופע הינו 'null' ( לא הועבר)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -64,7 +65,7 @@ msgstr "שם מאפיין האינדקס מסוג %s עבור בסיס %s שגו
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr "שם אינדקס לא תקין '%s' לסוג בסיס '%s'"
+msgstr "שם אינדקס לא תקין '%s' לסוג בסיס %s"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
@@ -76,7 +77,7 @@ msgstr "בקריאה ל־‚%s’:"
#: core/ustring.cpp
msgid "B"
-msgstr "ב׳"
+msgstr "B"
#: core/ustring.cpp
msgid "KiB"
@@ -124,15 +125,15 @@ msgstr "ערך:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr "הכנס מפתח כאן"
+msgstr "הכנס כאן מפתח"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr "לשכפל את הקבצים הנבחרים"
+msgstr "שכפול מפתח(ות) שנבחרו"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr "למחוק את הקבצים הנבחרים"
+msgstr "מחיקת מפתח(ות) שנבחרו"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
@@ -247,7 +248,7 @@ msgstr "פונקציות:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr "רצועות שמע:"
+msgstr "קטעי שמע:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
@@ -259,7 +260,7 @@ msgstr "החלפת נתיב רצועה"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "הפעל/כבה רצועה."
+msgstr "הפעלת/כיבוי רצועה זו."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
@@ -267,11 +268,11 @@ msgstr "עדכן מצב (איך המאפיין הזה נקבע)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
-msgstr "מצב אינתרפולציה"
+msgstr "מצב אינטרפולציה"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr ""
+msgstr "מצב לולאה Wrap (אינטרפולציה של הסוף עם ההתחלה בלולאה)"
#: editor/animation_track_editor.cpp
msgid "Remove this track."
@@ -283,7 +284,7 @@ msgstr "זמן (שניות): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr ""
+msgstr "הפעלת/ביטול רצועה"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -316,11 +317,11 @@ msgstr "מעוקב"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr ""
+msgstr "אינטרפולצית לולאה מסוג Clamp"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr ""
+msgstr "אינטרפולצית לולאה מסוג Wrap"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -336,7 +337,6 @@ msgid "Delete Key(s)"
msgstr "מחיקת מפתח(ות)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Update Mode"
msgstr "שינוי מצב עדכון הנפשה"
@@ -373,7 +373,6 @@ msgid "Create"
msgstr "יצירה"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Insert"
msgstr "הוסף הנפשה"
@@ -400,9 +399,8 @@ msgid "Change Animation Step"
msgstr "ניקוי ההנפשה"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rearrange Tracks"
-msgstr "סידור רצועות"
+msgstr "סדר רצועות מחדש"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
@@ -430,7 +428,7 @@ msgstr "נגן הנפשה אינו יכול להנפיש את עצמו, רק ש
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "אי אפשר להוסיף רצועה חדשה בלי שורש"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
@@ -469,23 +467,20 @@ msgid "Add Method Track Key"
msgstr "הוספת רצועות חדשות."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object: "
-msgstr "לא נמצא VariableGet בסקריפט: "
+msgstr "לא נמצאה מתודה בעצם: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Clipboard is empty"
-msgstr "לוח גזירי המשאבים ריק!"
+msgstr "לוח העתקה ריק"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
-msgstr "הדבקת משתנים"
+msgstr "הדבקת רצועות"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
@@ -494,7 +489,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
-msgstr ""
+msgstr "אפשרות זו אינה פעילה לעריכת בזייה, כי זאת רק רצועה אחת."
#: editor/animation_track_editor.cpp
msgid ""
@@ -508,40 +503,46 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"ההנפשה שייכת לסצנה מיובאת, לכן שינויים לרצועות המיובאות לא ישמרו.\n"
+"\n"
+"להפעלת האפשרות להוספת רצועות מותאמות-אישית, יש לקבוע בהגדרות ייבוא של הסצנה "
+"את\n"
+"\"הנפשה > אחסון\" ל-\"קבצים\", להפעיל את \"הנפשה > השאר רצועות מותאמות-אישית"
+"\", ולבסוף לייבא מחדש.\n"
+"דרך אחרת, להשתמש בהגדרות ייבוא אשר מייבאים הנפשות לקבצים נפרדים."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "אזהרה: עריכת הנפשה מיובאת"
#: editor/animation_track_editor.cpp
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr ""
+msgstr "יש לבחור במפרק AnimationPlayer כדי ליצור ולערוך הנפשות."
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr ""
+msgstr "הצגת רצועות רק של מפרקים שנבחרו בעץ."
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
-msgstr ""
+msgstr "קיבוץ רצועות לפי מפרק או הצגה כרשימה פשוטה."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "הצמדה"
+msgstr "הצמדה:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation step value."
-msgstr "שקופיות ההנפשה"
+msgstr "ערך צעד של הנפשה."
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "שניות"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
-msgstr ""
+msgstr "FPS"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -558,9 +559,8 @@ msgid "Animation properties."
msgstr "מאפייני ההנפשה."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Copy Tracks"
-msgstr "העתקת משתנים"
+msgstr "העתקת רצועות"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -665,7 +665,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 "העתק"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -703,7 +703,7 @@ msgstr "מעבר לשורה"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr "מספר השורה:"
+msgstr "שורה מספר:"
#: editor/code_editor.cpp
msgid "%d replaced."
@@ -711,7 +711,7 @@ msgstr "%d הוחלף."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr "%d התאמות."
+msgstr "%d התאמה."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
@@ -725,9 +725,9 @@ msgstr "התאמת רישיות"
msgid "Whole Words"
msgstr "מילים שלמות"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
-msgstr "להחליף"
+msgstr "החלף"
#: editor/code_editor.cpp
msgid "Replace All"
@@ -921,6 +921,11 @@ msgid "Signals"
msgstr "אותות"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "מאפייני פריט."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -934,9 +939,8 @@ msgid "Edit..."
msgstr "עריכה..."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Go To Method"
-msgstr "שיטות"
+msgstr "מעבר למתודה"
#: editor/create_dialog.cpp
msgid "Change %s Type"
@@ -960,7 +964,7 @@ msgid "Recent:"
msgstr "אחרונים:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "חיפוש:"
@@ -1127,7 +1131,7 @@ msgstr "תודה רבה מקהילת Godot!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr "מתנדבי מנוע Godot"
+msgstr "מתנדבי מנוע גודו"
#: editor/editor_about.cpp
msgid "Project Founders"
@@ -1137,6 +1141,9 @@ msgstr "מקימי המיזם"
msgid "Lead Developer"
msgstr "מפתחים ראשיים"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "מנהל המיזם "
@@ -1158,6 +1165,16 @@ msgid "Gold Sponsors"
msgstr "מממני זהב"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "תורמים בדרגת כסף"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "תורמים בדרגת ארד"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "מממנים זעירים"
@@ -1212,9 +1229,8 @@ msgid "Error opening package file, not in ZIP format."
msgstr "פתיחת קובץ החבילה נכשלה, המבנה אינו zip."
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (Already Exists)"
-msgstr "הפעולה ‚%s’ כבר קיימת!"
+msgstr "%s (כבר קיים)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
@@ -1636,21 +1652,21 @@ msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "ייבוא"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "שם המפרק:"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "מערכת קבצים"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "ייבוא"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "להחליף הכול"
@@ -1801,13 +1817,11 @@ msgid "Copy Path"
msgstr "העתקת נתיב"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "הצגה במנהל הקבצים"
+msgstr "פתיחה במנהל הקבצים"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
msgstr "הצגה במנהל הקבצים"
@@ -1857,39 +1871,39 @@ msgstr "שמירת קובץ"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr "חזרה אחורה"
+msgstr "מעבר אחורה"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr "התקדמות קדימה"
+msgstr "מעבר קדימה"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr "עלייה למעלה"
+msgstr "מעבר מעלה"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "החלפת מצב תצוגה לקבצים מוסתרים"
+msgstr "הצג/הסתר קבצים מוסתרים"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "החלפת מצב מועדפים"
+msgstr "הוספת/ביטול מועדף"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr "החלפת מצב"
+msgstr "שינוי מצב"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "התמקדות על נתיב"
+msgstr "מיקוד נתיב"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "העברת מועדף למעלה"
+msgstr "העברת מועדף מעלה"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr "העברת מועדף למטה"
+msgstr "העברת מועדף מטה"
#: editor/editor_file_dialog.cpp
msgid "Go to previous folder."
@@ -1900,18 +1914,16 @@ 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 scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
@@ -1931,7 +1943,7 @@ msgstr "תיקיות וקבצים:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "תצוגה מקדימה:"
@@ -1951,11 +1963,11 @@ msgstr "סריקת מקורות"
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
-msgstr ""
+msgstr "יש מספר מייבאים לסוגים שונים המצביעים לקובץ %s, הייבוא בוטל"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr ""
+msgstr "ייבוא משאבים (מחדש)"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
@@ -1975,14 +1987,12 @@ msgid "Inherited by:"
msgstr "מוריש אל:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "תיאור:"
+msgstr "תיאור"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "מסמכים מקוונים"
+msgstr "הדרכות מקוונות"
#: editor/editor_help.cpp
msgid "Properties"
@@ -1990,21 +2000,19 @@ msgstr "מאפיינים"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "דריסה:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "טעינת בררת המחדל"
+msgstr "ברירת מחדל:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr "שיטות"
+msgstr "מתודות"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Theme Properties"
-msgstr "מאפיינים"
+msgstr "מאפייני ערכת עיצוב"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2015,31 +2023,32 @@ msgid "Constants"
msgstr "קבועים"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "תיאור המאפיין:"
+msgstr "תיאורי מאפיינים"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "ערך:"
+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 ""
+"כרגע אין תיאור למאפיין זה. בבקשה עזור לנו על-ידי [/color][/url]כתיבת "
+"תיאור[url=$url][color=$color]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "תיאור השיטה:"
+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 ""
+"כרגע אין תיאור למתודה זו. בבקשה עזור לנו על-ידי [/url][/color]כתיבת תיאור "
+"[color=$color][url=$url]!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -2051,99 +2060,84 @@ msgid "Case Sensitive"
msgstr "תלוי רישיות"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "חיפוש"
+msgstr "הצג היררכיה"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Display All"
-msgstr "הצגה נורמלית"
+msgstr "הצג הכל"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Classes Only"
-msgstr "מחלקות"
+msgstr "מחלקות בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Methods Only"
-msgstr "שיטות"
+msgstr "מתודות בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "אותות"
+msgstr "אותות בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Constants Only"
-msgstr "קבועים"
+msgstr "קבועים בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Properties Only"
-msgstr "מאפיינים"
+msgstr "מאפיינים בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Properties Only"
-msgstr "מאפיינים"
+msgstr "מאפייני ערכת עיצוב בלבד"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Member Type"
-msgstr "חברים"
+msgstr "סוג שדה"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Class"
-msgstr "מחלקה:"
+msgstr "מחלקה"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "שיטות"
+msgstr "מתודה"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "אותות"
+msgstr "אות"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
msgstr "קבוע"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "מאפיינים"
+msgstr "מאפיין"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "מאפיינים"
+msgstr "מאפיין ערכת עיצוב"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "מאפיין:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr ""
+msgstr "קבע"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "קביעה מרובה:"
#: editor/editor_log.cpp
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_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2153,11 +2147,11 @@ msgstr "הסרת הבחירה"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "מחיקה"
+msgstr "ניקוי"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "מחיקת הפלט"
+msgstr "ניקוי פלט"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
@@ -2167,20 +2161,19 @@ msgstr "עצירה"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
msgid "Start"
-msgstr ""
+msgstr "התחלה"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s לשנייה"
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
msgstr "הורדה"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "העלאה"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2188,32 +2181,32 @@ msgstr "מפרק"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "RPC נכנס"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "RSET נכנס"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "RPC יוצא"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "RSET יוצא"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "חלון חדש"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "משאבים מיובאים לא נשמרו."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "אישור"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
@@ -2224,6 +2217,7 @@ 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..."
@@ -2235,7 +2229,7 @@ msgstr "לא ניתן לפתוח קובץ לכתיבה:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr "תבנית הקובץ המבוקשת לא ידועה:"
+msgstr "סוג הקובץ המבוקש לא ידוע:"
#: editor/editor_node.cpp
msgid "Error while saving."
@@ -2243,27 +2237,27 @@ 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 ""
+msgstr "לא יכול לפתוח את 's%'. יכול להיות שהקובץ הועבר או נמחק."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr "הפענוח של ‚%s’ נכשל."
+msgstr "שגיאה בפענוח 's%'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr "סוף הקובץ בלתי צפוי ‚%s’."
+msgstr "סוף קובץ בלתי צפוי '%s'."
#: editor/editor_node.cpp
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "חסר 's%' או תלות שלו."
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
-msgstr "הטעינה של ‚%s’ נכשלה."
+msgstr "שגיאה בטעינת 's%'."
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr "הסצנה נשמרת"
+msgstr "שומר סצנה"
#: editor/editor_node.cpp
msgid "Analyzing"
@@ -2271,7 +2265,7 @@ msgstr "מתבצע ניתוח"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr "נוצרת תמונה ממוזערת"
+msgstr "יצירת תמונה ממוזערת"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
@@ -2282,34 +2276,34 @@ 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!"
-msgstr ""
+msgstr "לא ניתן לטעון את MeshLibrary למיזוג!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "שגיאה בשמירת MeshLibrary!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr ""
+msgstr "לא ניתן לטעון TileSet למיזוג!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr ""
+msgstr "שגיאה בשמירת TileSet!"
#: editor/editor_node.cpp
msgid "Error trying to save layout!"
@@ -2317,7 +2311,7 @@ msgstr "שמירת הפריסה נכשלה!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr "בררת המחדל של פריסת העורך שוכתבה."
+msgstr "ברירת המחדל של עורך הפריסה נדרסה."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2325,7 +2319,7 @@ msgstr "שם הפריסה לא נמצא!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
-msgstr "פריסת בררת המחדל שוחזרה להגדרות הבסיס."
+msgstr "פריסת ברירת המחדל שוחזרה להגדרות הבסיס."
#: editor/editor_node.cpp
msgid ""
@@ -2333,20 +2327,24 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"משאב זה שייך לסצנה שיובאה ולא ניתן לעריכה.\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
msgid ""
@@ -2355,6 +2353,9 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"סצנה זו מיובאת, כל שינוי בה לא יישמר.\n"
+"יצירת מופע או ירושה תאפשר לעשות בה שינויים.\n"
+"בבקשה קרא/י את התיעוד הקשור לייבוא סצנות כדי להבין טוב יותר את שיטת העבודה."
#: editor/editor_node.cpp
msgid ""
@@ -2362,6 +2363,8 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
+"זהו אובייקט מרוחק לכן שינויים בו לא יישמרו.\n"
+"בבקשה קרא/י את התיועד הקשור לניפוי שגיאות כדי להבין טוב יותר את שיטת העבודה."
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
@@ -2380,9 +2383,8 @@ msgid "Open Base Scene"
msgstr "פתיחת סצנת בסיס"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "פתיחת סצנה מהירה…"
+msgstr "פתיחה מהירה…"
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2398,16 +2400,15 @@ msgstr "שמירה וסגירה"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
-msgstr "לשמור את השינויים ל־‚%s’ לפני הסגירה?"
+msgstr "לשמור את השינויים ל־'%s' לפני הסגירה?"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Saved %s modified resource(s)."
-msgstr "טעינת המשאב נכשלה."
+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..."
@@ -2431,7 +2432,7 @@ msgstr "לא ניתן לבצע פעולה זו ללא סצנה."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "ייצוא Mesh Library"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
@@ -2439,7 +2440,7 @@ msgstr "לא ניתן לבצע פעולה זו ללא מפרק עליון."
#: editor/editor_node.cpp
msgid "Export Tile Set"
-msgstr ""
+msgstr "ייצוא Tile Set"
#: editor/editor_node.cpp
msgid "This operation can't be done without a selected node."
@@ -2454,19 +2455,20 @@ msgid "Can't reload a scene that was never saved."
msgstr "לא ניתן לרענן סצנה שמעולם לא נשמרה."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reload Saved Scene"
-msgstr "שמירת סצנה"
+msgstr "טעינה מחדש של סצינה שמורה"
#: editor/editor_node.cpp
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"הסצינה הנוכחית כוללת שינויים שלא נשמרו.\n"
+"האם לטעון מחדש את הסצינה? לא ניתן לבטל פעולה זו."
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
-msgstr ""
+msgstr "הפעלה מהירה של הסצנה..."
#: editor/editor_node.cpp
msgid "Quit"
@@ -2509,56 +2511,61 @@ msgid "Close Scene"
msgstr "סגירת סצנה"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "סגירת סצנה"
+msgstr "פתיחה מחדש של סצנה סגורה"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
-msgstr "לא ניתן לפתוח את תוסף ההרחבות תחת: ‚%s’ פענוח ההגדרות נכשל."
+msgstr "לא ניתן לפתוח את תוסף ההרחבות בנתיב: '%s' פענוח ההגדרות נכשל."
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "לא ניתן למצוא שדה סקריפט עבור תוסף הרחבה תחת ‚res://addons/%s’."
+msgstr "לא ניתן למצוא שדה סקריפט עבור תוסף הרחבה בנתיב 'res://addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr "לא ניתן לטעון סקריפט הרחבה מהנתיב: ‚%s’."
+msgstr "לא ניתן לטעון סקריפט הרחבה מנתיב: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"לא ניתן לטעון סקריפט הרחבה מנתיב: '%s' נראה שיש שגיאה בקוד, אנא בדוק את "
+"התחביר."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
-msgstr ""
+msgstr "לא ניתן לטעון סקריפט הרחבה מנתיב: '%s' סוג הבסיס אינו EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
-msgstr ""
+msgstr "לא ניתן לטעון סקריפט הרחבה מנתיב: '%s' סקריפט אינו מוגדר ככלי (tool)."
#: editor/editor_node.cpp
msgid ""
"Scene '%s' was automatically imported, so it can't be modified.\n"
"To make changes to it, a new inherited scene can be created."
msgstr ""
+"הסצינה '%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
msgid "Scene '%s' has broken dependencies:"
-msgstr ""
+msgstr "לסצינה '%s' יש תלות חסרה:"
#: editor/editor_node.cpp
msgid "Clear Recent Scenes"
-msgstr ""
+msgstr "נקה סצינות אחרונות"
#: editor/editor_node.cpp
msgid ""
@@ -2566,6 +2573,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"לא הוגדרה סצנה ראשית, לבחור אחת?\n"
+"אפשר לשנות זאת מאוחר יותר ב-\"הגדרות מיזם\" תחת הקטגוריה 'יישום'."
#: editor/editor_node.cpp
msgid ""
@@ -2573,6 +2582,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"הסצינה שנבחרה '%s' לא קיימת, לבחור סצנה קיימת?\n"
+"אפשר לשנות זאת מאוחר יותר ב\"הגדרות מיזם\" תחת הקטגוריה 'יישום'."
#: editor/editor_node.cpp
msgid ""
@@ -2580,81 +2591,78 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"הסצינה שנבחרה '%s' אינה קובץ סצינה, לבחור קובץ סצינה אחר?\n"
+"אפשר לשנות זאת מאוחר יותר ב-\"הגדרות מיזם\" תחת הקטגוריה 'יישום'."
#: editor/editor_node.cpp
msgid "Save Layout"
-msgstr ""
+msgstr "שמירת פריסה"
#: editor/editor_node.cpp
msgid "Delete Layout"
-msgstr ""
+msgstr "מחיקת פריסה"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr ""
+msgstr "בחירת מחדל"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
-#, fuzzy
msgid "Show in FileSystem"
-msgstr "הצגה במערכת הקבצים"
+msgstr "הצגה בחלון הקבצים"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Play This Scene"
-msgstr "נגינת הסצנה"
+msgstr "הרצת הסצנה"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "לסגור לשוניות אחרות"
+msgstr "סגירת לשונית"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo Close Tab"
-msgstr "לסגור לשוניות אחרות"
+msgstr "ביטול סגירת לשונית"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
-msgstr "לסגור לשוניות אחרות"
+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"
-msgstr ""
+msgstr "החלפת לשונית סצנה"
#: editor/editor_node.cpp
msgid "%d more files or folders"
-msgstr ""
+msgstr "%d קבצים או תיקיות נוספים"
#: editor/editor_node.cpp
msgid "%d more folders"
-msgstr ""
+msgstr "%d תיקיות נוספות"
#: editor/editor_node.cpp
msgid "%d more files"
-msgstr ""
+msgstr "%d קבצים נוספים"
#: editor/editor_node.cpp
msgid "Dock Position"
-msgstr ""
+msgstr "מיקום הפנל"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
-msgstr ""
+msgstr "מצב ללא הסחות דעת"
#: editor/editor_node.cpp
msgid "Toggle distraction-free mode."
-msgstr ""
+msgstr "הפעל/בטל מצב ללא הסחות דעת."
#: editor/editor_node.cpp
msgid "Add a new scene."
@@ -2666,12 +2674,11 @@ msgstr "סצנה"
#: editor/editor_node.cpp
msgid "Go to previously opened scene."
-msgstr "מעבר לסצנה שנפתחה קודם לכן."
+msgstr "מעבר לסצנה הקודמת."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Copy Text"
-msgstr "העתקת נתיב"
+msgstr "העתקת טקסט"
#: editor/editor_node.cpp
msgid "Next tab"
@@ -2683,7 +2690,7 @@ msgstr "הלשונית הקודמת"
#: editor/editor_node.cpp
msgid "Filter Files..."
-msgstr ""
+msgstr "סנן קבצים..."
#: editor/editor_node.cpp
msgid "Operations with scene files."
@@ -2710,7 +2717,6 @@ msgid "Save Scene"
msgstr "שמירת סצנה"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
msgstr "שמירת כל הסצנות"
@@ -2720,11 +2726,11 @@ msgstr "המרה אל…"
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "MeshLibrary..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr ""
+msgstr "TileSet..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2750,17 +2756,16 @@ msgid "Project Settings..."
msgstr "הגדרות מיזם..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "גרסה:"
+msgstr "בקרת גירסאות"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "קביעת בקרת גירסאות"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "סגור בקרת גירסאות"
#: editor/editor_node.cpp
msgid "Export..."
@@ -2768,7 +2773,7 @@ msgstr "ייצוא..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "התקנת תבנית בנייה לאנדרואיד..."
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
@@ -2784,7 +2789,7 @@ msgstr "סייר משאבים יתומים ..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr "יציאה לרשימת המיזמים"
+msgstr "יציאה לרשימת מיזמים"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2797,69 +2802,89 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"בעת ייצוא או הטמעה, קובץ ההפעלה ינסה להתחבר לכתובת ה־IP של המחשב הזה לצורך "
-"ניפוי שגיאות."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "הטמעה קטנה עם מערכת קבצים ברשת"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
+"כאשר אפשרות זו מופעלת, ייצוא או פריסה יפיקו קובץ הפעלה מינימלי.\n"
+"מערכת הקבצים תסופק מהמיזם על ידי העורך ברשת.\n"
+"באנדרואיד, הפריסה תשתמש בכבל USB לביצועים מהירים יותר. אפשרות זו מזרזת בדיקה "
+"של משחקים עם קובץ הרצה גדול."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "צורות התנגשות גלויים"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
+"צורות התנגשויות ומפרקי קרניים (עבור דו ותלת מימד) יהיו גלויים בהרצת המשחק אם "
+"אפשרות זאת מופעלת."
#: editor/editor_node.cpp
msgid "Visible Navigation"
msgstr "ניווט גלוי"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
-msgstr ""
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
+msgstr "רשתות ניווט ומצולעים יהיו גלויים בהרצת המשחק אם אפשרות זאת מופעלת."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "סנכרון השינויים בסצנה"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
+"כאשר אפשרות זו מופעלת, כל השינויים שיבוצעו בסצנה בעורך יוצגו בהרצת המשחק.\n"
+"בשימוש עם מכשיר מרוחק, מערכת קבצים ברשת (NFS) תהיה יעילה יותר ."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "סנכרון השינויים בסקריפט"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
+"כאשר אפשרות זו מופעלת, כל סקריפט שנשמר יטען מחדש בהרצת המשחק.\n"
+"בשימוש עם מכשיר מרוחק, מערכת קבצים ברשת (NFS) תהיה יעילה יותר ."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
@@ -2874,46 +2899,40 @@ 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 "הגדרות עורך"
+msgstr "צילומי מסך נשמרים בתיקיית נתוני/הגדרות העורך."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "כניסה אל/יציאה ממסך מלא"
+msgstr "הפעלת/ביטול מסך מלא"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Toggle System Console"
-msgstr "החלפת מצב"
+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
-#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr "הגדרות עורך"
+msgstr "פתיחת תיקיית הגדרות העורך"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Editor Features..."
-msgstr "ניהול תבניות ייצוא"
+msgstr "ניהול תכונות העורך..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "ניהול תבניות ייצוא"
+msgstr "ניהול תבניות ייצוא..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
@@ -2924,7 +2943,7 @@ msgstr "עזרה"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "חיפוש"
@@ -2938,13 +2957,12 @@ msgid "Q&A"
msgstr "שאלות ותשובות נפוצות"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "ייבוא מחדש"
+msgstr "דיווח על תקלה (באג)"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "שליחת משוב על התיעוד"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -2952,19 +2970,19 @@ msgstr "קהילה"
#: editor/editor_node.cpp
msgid "About"
-msgstr "על"
+msgstr "על אודות"
#: editor/editor_node.cpp
msgid "Play the project."
-msgstr "נגינת המיזם…"
+msgstr "הרצת המיזם."
#: editor/editor_node.cpp
msgid "Play"
-msgstr "נגינה"
+msgstr "הרצה"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "הפסקת הרצת הסצנה לניפוי שגיאות."
#: editor/editor_node.cpp
msgid "Pause Scene"
@@ -2976,49 +2994,44 @@ msgstr "עצירת הסצנה."
#: editor/editor_node.cpp
msgid "Play the edited scene."
-msgstr "נגינת הסצנה שנערכה."
+msgstr "הרצת הסצנה שנערכה."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "נגינת הסצנה"
+msgstr "הרצת הסצנה"
#: editor/editor_node.cpp
msgid "Play custom scene"
-msgstr "נגינת סצנה מותאמת אישית"
+msgstr "הרצת סצנה מותאמת אישית"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr "נגינת סצנה בהתאמה אישית"
+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
-#, fuzzy
msgid "Save & Restart"
-msgstr "לשמור ולצאת"
+msgstr "שמירה והפעלה מחדש"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Spins when the editor window redraws."
-msgstr "מסתובב כאשר חלון העורך מצויר מחדש!"
+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"
@@ -3029,9 +3042,8 @@ msgid "Inspector"
msgstr "חוקר"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Expand Bottom Panel"
-msgstr "להרחיב הכול"
+msgstr "הרחבת פאנל תחתון"
#: editor/editor_node.cpp
msgid "Output"
@@ -3043,12 +3055,11 @@ msgstr "לא לשמור"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
-msgstr ""
+msgstr "חסרה תבנית בנייה לאנדרואיד, נא להתקין תבניות רלוונטיות."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "ניהול תבניות ייצוא"
+msgstr "ניהול תבניות"
#: editor/editor_node.cpp
msgid ""
@@ -3060,6 +3071,12 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"פעולה זו תגדיר את המיזם שלך לבניית אנדרואיד מותאמת אישית על ידי התקנת תבנית "
+"המקור ל- \"res://android/build\".\n"
+"לאחר מכן אפשר להחיל שינויים ולבנות APK מותאם אישית בייצוא (הוספת מודולים, "
+"שינוי AndroidManifest.xml, וכו').\n"
+"כדי לערוך בנייה מותאמת אישית במקום שימוש בתבנית קיימת, יש לאפשר את \"השתמש "
+"בבניה מותאמת אישית\" בהגדרות הייצוא לאנדרואיד."
#: editor/editor_node.cpp
msgid ""
@@ -3127,9 +3144,8 @@ msgid "Open the previous Editor"
msgstr "פתיחת העורך הקודם"
#: editor/editor_node.h
-#, fuzzy
msgid "Warning!"
-msgstr "אזהרות"
+msgstr "אזהרה!"
#: editor/editor_path.cpp
msgid "No sub-resources found."
@@ -3340,7 +3356,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -3596,9 +3613,8 @@ msgid "Download Templates"
msgstr "הורדת תבניות"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr "בחירת אתר מראה מהרשימה: "
+msgstr "בחר אתר חלופי מהרשימה: (Shift+Click: פתיחה בדפדפן)"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3663,9 +3679,8 @@ msgid "Duplicating folder:"
msgstr "תיקייה משוכפלת:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
-msgstr "סצנה חדשה בירושה…"
+msgstr "סצנה חדשה יורשת"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3800,9 +3815,8 @@ msgid "Create Script"
msgstr "יצירת סקריפט"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Find in Files"
-msgstr "איתור…"
+msgstr "איתור בקבצים"
#: editor/find_in_files.cpp
#, fuzzy
@@ -3869,9 +3883,8 @@ msgid "Remove from Group"
msgstr "הסרה מקבוצה"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group name already exists."
-msgstr "הפעולה ‚%s’ כבר קיימת!"
+msgstr "שם הקבוצה כבר קיים."
#: editor/groups_editor.cpp
#, fuzzy
@@ -4064,9 +4077,8 @@ msgid "Copy Params"
msgstr "העתקת משתנים"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource Clipboard"
-msgstr "לוח גזירי המשאבים ריק!"
+msgstr "ערוך לוח העתקת משאבים"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
@@ -4308,9 +4320,8 @@ msgid "Open Animation Node"
msgstr "שם הנפשה חדשה:"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "הפעולה ‚%s’ כבר קיימת!"
+msgstr "המשולש כבר קיים."
#: editor/plugins/animation_blend_space_2d_editor.cpp
#, fuzzy
@@ -4365,14 +4376,13 @@ 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
msgid "Edit Filters"
-msgstr ""
+msgstr "עריכת מסננים"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
@@ -4405,15 +4415,14 @@ 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 "מחיקת שורה"
+msgstr "מחק מפרק"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
@@ -4508,9 +4517,8 @@ msgid "Remove Animation"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Invalid animation name!"
-msgstr "שם שגוי."
+msgstr "שם הנפשה לא חוקי!"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -4539,14 +4547,12 @@ msgid "Duplicate Animation"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "תקריב הנפשה."
+msgstr "אין הנפשה להעתקה!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "לא בנתיב המשאב."
+msgstr "אין משאב הנפשה בלוח ההעתקה!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
@@ -4557,9 +4563,8 @@ msgid "Paste Animation"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "שם הנפשה חדשה:"
+msgstr "אין הנפשה לעריכה!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
@@ -4702,9 +4707,8 @@ msgid "Move Node"
msgstr "מצב הזזה (W)"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "מעברון"
+msgstr "המעברון קיים!"
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -5176,7 +5180,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -6473,7 +6477,7 @@ msgstr "הזזת נקודה"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
-msgstr ""
+msgstr "מאפיין 'skeleton' של Polygon2D אינו מצביע על מפרק Skeleton2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6648,9 +6652,8 @@ msgid "Show Grid"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Configure Grid:"
-msgstr "הגדרת הצמדה…"
+msgstr "הגדר רשת:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset X:"
@@ -7038,9 +7041,8 @@ msgid "Line"
msgstr "שורה:"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function"
-msgstr "מעבר לפונקציה…"
+msgstr "עבור לפונקציה"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
@@ -7896,7 +7898,8 @@ msgid "New Animation"
msgstr "שם הנפשה חדשה:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "מהירות (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8841,9 +8844,8 @@ msgid "Create Shader Node"
msgstr "יצירת תיקייה"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "מעבר לפונקציה…"
+msgstr "פונקציית צבע."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
@@ -9333,9 +9335,8 @@ msgid "Transform uniform."
msgstr "התמרה"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "מעבר לפונקציה…"
+msgstr "פונקציה וקטורית."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
@@ -9983,6 +9984,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "מנהל המיזמים"
@@ -10061,9 +10063,8 @@ msgid ""
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"
@@ -10426,11 +10427,16 @@ msgid "Batch Rename"
msgstr "שינוי שם"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "להחליף "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10481,7 +10487,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10543,8 +10549,9 @@ msgid "Reset"
msgstr "איפוס התקריב"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "גרסה נוכחית:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10657,7 +10664,6 @@ msgid "Delete %d nodes and any children?"
msgstr "מחיקת שורה"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
msgstr "מחק %d מפרקים?"
@@ -10953,19 +10959,16 @@ 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
@@ -11063,9 +11066,8 @@ msgid "Will load an existing script file."
msgstr "טעינת פריסת אפיקי שמע."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script file already exists."
-msgstr "הפעולה ‚%s’ כבר קיימת!"
+msgstr "קובץ סקריפט כבר קיים."
#: editor/script_create_dialog.cpp
msgid ""
@@ -11642,334 +11644,324 @@ 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 ""
+"מפרק ביצע yield ללא זיכרון עבודה, אנא קרא את התיעוד על איך לעשות yield כראוי!"
#: modules/visual_script/visual_script.cpp
msgid ""
"Node yielded, but did not return a function state in the first working "
"memory."
-msgstr ""
+msgstr "המפרק ביצע yield, אבל לא החזיר את מצב הפונקציה בזיכרון העבודה הראשון."
#: 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 ""
+msgstr "מפרק החזיר פלט סדר (sequence) לא חוקי: "
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
-msgstr ""
+msgstr "סיבית הסדר (sequence bit) נמצאה אבל המפרק לא במחסנית, דווח על שגיאה!"
#: modules/visual_script/visual_script.cpp
msgid "Stack overflow with stack depth: "
-msgstr ""
+msgstr "גלישת מחסנית עם עומק מחסנית: "
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Signal Arguments"
-msgstr ""
+msgstr "שינוי ארגומנטים של אות"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Argument Type"
-msgstr ""
+msgstr "שינוי סוג ארגומנט"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Argument name"
-msgstr ""
+msgstr "שינוי שם ארגומנט"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Default Value"
-msgstr ""
+msgstr "קביעת ערך ברירת מחדל של משתנה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Type"
-msgstr ""
+msgstr "קביעת סוג משתנה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "מועדפים:"
+msgstr "הוספת פורט כניסה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "מועדפים:"
+msgstr "הוספת פורט יציאה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Override an existing built-in function."
-msgstr "שם שגוי. לא יכול לחפוף לשם סוג מובנה קיים."
+msgstr "דריסה של פונקציה מובנת קיימת."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "יצירת %s חדש"
+msgstr "יצירת פונקציה חדשה."
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
-msgstr ""
+msgstr "משתנים:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new variable."
-msgstr "יצירת %s חדש"
+msgstr "יצירת משתנה חדש."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "אותות:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "יצירת מצולע"
+msgstr "יצירת אות חדש."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
-msgstr ""
+msgstr "השם אינו מזהה חוקי:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
-msgstr ""
+msgstr "השם כבר בשימוש של פונקציה/משתנה/אות אחר:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Function"
-msgstr ""
+msgstr "שינוי שם פונקציה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Variable"
-msgstr ""
+msgstr "שינוי שם משתנה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Signal"
-msgstr ""
+msgstr "שינוי שם אות"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Function"
-msgstr ""
+msgstr "הוספת פונקציה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "הסרת נקודה בנתיב"
+msgstr "מחיקת פורט כניסה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
-msgstr ""
+msgstr "הוספת משתנה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Signal"
-msgstr ""
+msgstr "הוספת אות"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "הסרת נקודה בנתיב"
+msgstr "הסרת פורט כניסה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "הסרת נקודה בנתיב"
+msgstr "הסרת פורט יציאה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
-msgstr ""
+msgstr "שינוי ביטוי"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
-msgstr ""
+msgstr "הסרת מפרקי VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Duplicate VisualScript Nodes"
-msgstr ""
+msgstr "שכפול מפרקי VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
msgstr ""
+"החזק את %s כדי להוסיף Getter. החזק את מקש Shift כדי להוסיף חתימה גנרית."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
msgstr ""
+"החזק את מקש Ctrl כדי להוסיף Getter. החזק את מקש Shift כדי להוסיף חתימה גנרית."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a simple reference to the node."
-msgstr ""
+msgstr "החזק את %s כדי להוסיף הפניה פשוטה למפרק."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a simple reference to the node."
-msgstr ""
+msgstr "החזק את מקש Ctrl כדי להוסיף הפניה פשוטה למפרק."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Variable Setter."
-msgstr ""
+msgstr "החזק את %s כדי להוסיף Setter למשתנה."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a Variable Setter."
-msgstr ""
+msgstr "החזק את מקש Ctrl כדי להוסיף  Setter למשתנה."
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Preload Node"
-msgstr ""
+msgstr "הוספת מפרק קדם טעינה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node(s) From Tree"
-msgstr ""
+msgstr "הוספת מפרק/ים מהעץ"
#: modules/visual_script/visual_script_editor.cpp
msgid ""
"Can't drop properties because script '%s' is not used in this scene.\n"
"Drop holding 'Shift' to just copy the signature."
msgstr ""
+"לא ניתן להוסיף מאפיינים כי סקריפט '%s' לא בשימוש בסצנה זו.\n"
+"החזקת 'Shift' בזמן הוספה תעתיק רק את החתימה."
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Getter Property"
-msgstr ""
+msgstr "הוספת מאפיין ל-Getter"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Setter Property"
-msgstr ""
+msgstr "הוספת מאפיין ל-Setter"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Base Type"
-msgstr ""
+msgstr "שינוי סוג בסיס"
#: modules/visual_script/visual_script_editor.cpp
msgid "Move Node(s)"
-msgstr ""
+msgstr "הזזת מפרק(ים)"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Node"
-msgstr ""
+msgstr "הסרת מפרק VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Connect Nodes"
-msgstr ""
+msgstr "חיבור מפרקים"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Disconnect Nodes"
-msgstr "מנותק"
+msgstr "ניתוק מפרקים"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Data"
-msgstr "התחברות למפרק:"
+msgstr "קישור נתוני ‫מפרק"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Sequence"
-msgstr "התחברות למפרק:"
+msgstr "קישור Sequence של מפרק"
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
-msgstr ""
+msgstr "לסקריפט יש כבר פונקציה '%s'"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Input Value"
-msgstr ""
+msgstr "שינוי ערך נקלט"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "החלפת מצב הערה"
+msgstr "שינוי גודל הערה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
-msgstr ""
+msgstr "לא ניתן להעתיק את פונקצית המפרק."
#: modules/visual_script/visual_script_editor.cpp
msgid "Clipboard is empty!"
-msgstr ""
+msgstr "לוח העתקה ריק!"
#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
-msgstr ""
+msgstr "הדבקת מפרקי VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function with a function node."
-msgstr ""
+msgstr "לא ניתן ליצור פונקציה עם פונקצית המפרק."
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function of nodes from nodes of multiple functions."
-msgstr ""
+msgstr "לא ניתן ליצור פונקציה של מפרקים ממפרקים של פונקציות מרובות."
#: modules/visual_script/visual_script_editor.cpp
msgid "Select at least one node with sequence port."
-msgstr ""
+msgstr "בחר מפרק אחד לפחות עם כניסה רציפה (Sequence)."
#: modules/visual_script/visual_script_editor.cpp
msgid "Try to only have one sequence input in selection."
-msgstr ""
+msgstr "יש לנסות בחירה של רק כניסה רציפה אחת."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "יצירת %s חדש"
+msgstr "יצירת פונקציה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
-msgstr ""
+msgstr "הסרת פונקציה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Variable"
-msgstr ""
+msgstr "הסרת משתנה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Variable:"
-msgstr ""
+msgstr "עריכת משתנה:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Signal"
-msgstr ""
+msgstr "הסרת אות"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Signal:"
-msgstr ""
+msgstr "עריכת אות:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Make Tool:"
-msgstr ""
+msgstr "יצירת כלי:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
-msgstr "חברים:"
+msgstr "שדות:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "שינוי ערך בררת המחדל"
+msgstr "שינוי סוג הבסיס:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "הזזת נקודה"
+msgstr "הוספת מפרקים..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "מעבר לפונקציה…"
+msgstr "הוספת פונקציה…"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "פונקציות:"
+msgstr "שם_פונקציה"
#: modules/visual_script/visual_script_editor.cpp
msgid "Select or create a function to edit its graph."
-msgstr ""
+msgstr "יש לבחור או ליצור פונקציה לעריכת התרשים שלה."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr ""
+msgstr "מחיקת הנבחר"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
-msgstr "איתור סוג מפרק"
+msgstr "איתור סוג המפרק"
#: modules/visual_script/visual_script_editor.cpp
msgid "Copy Nodes"
@@ -11980,19 +11972,16 @@ msgid "Cut Nodes"
msgstr "גזירת מפרקים"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "פונקציות:"
+msgstr "יצירת פונקציה"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "רענון"
+msgstr "רענון תרשים"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
-msgstr "חברים"
+msgstr "עריכת שדה"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
@@ -12000,11 +11989,11 @@ msgstr "סוג הקלט לא זמין למחזוריות: "
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid"
-msgstr ""
+msgstr "איטרטור הפך ללא חוקי"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid: "
-msgstr ""
+msgstr "איטרטור הפך ללא חוקי: "
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
@@ -12020,7 +12009,7 @@ msgstr "הנתיב לא מוביל מפרק!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name '%s' in node %s."
-msgstr ""
+msgstr "שם מאפיין אינדקס לא חוקי '%s' במפרק %s."
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
@@ -12047,43 +12036,43 @@ msgid ""
"Invalid return value from _step(), must be integer (seq out), or string "
"(error)."
msgstr ""
+"ערך מוחזר לא חוקי מ-_step(), חייב להיות מספר שלם (seq out) או מחרוזת (שגיאה)."
#: modules/visual_script/visual_script_property_selector.cpp
-#, fuzzy
msgid "Search VisualScript"
-msgstr "חיפוש בעזרה"
+msgstr "חיפוש VisualScript"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
-msgstr ""
+msgstr "קבלת %s"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
-msgstr ""
+msgstr "קביעת %s"
#: platform/android/export/export.cpp
msgid "Package name is missing."
-msgstr ""
+msgstr "שם החבילה חסר."
#: platform/android/export/export.cpp
msgid "Package segments must be of non-zero length."
-msgstr ""
+msgstr "מקטעי החבילה חייבים להיות באורך שאינו אפס."
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
-msgstr ""
+msgstr "התו '%s' אינו מותר בשמות חבילת יישום אנדרואיד."
#: platform/android/export/export.cpp
msgid "A digit cannot be the first character in a package segment."
-msgstr ""
+msgstr "ספרה אינה יכולה להיות התו הראשון במקטע חבילה."
#: platform/android/export/export.cpp
msgid "The character '%s' cannot be the first character in a package segment."
-msgstr ""
+msgstr "התו '%s' אינו יכול להיות התו הראשון במקטע חבילה."
#: platform/android/export/export.cpp
msgid "The package must have at least one '.' separator."
-msgstr ""
+msgstr "החבילה חייבת לכלול לפחות מפריד '.' אחד."
#: platform/android/export/export.cpp
msgid "Select device from the list"
@@ -12091,121 +12080,135 @@ msgstr "נא לבחור התקן מהרשימה"
#: platform/android/export/export.cpp
msgid "ADB executable not configured in the Editor Settings."
-msgstr ""
+msgstr "קובץ ההפעלה של ADB לא נקבע בהגדרות העורך."
#: platform/android/export/export.cpp
msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr ""
+msgstr "OpenJDK jarsigner לא נקבע בהגדרות העורך."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
-msgstr ""
+msgstr "מפתח לניפוי שגיאות לא נקבע בהגדרות העורך ולא בהגדרות הייצוא."
#: platform/android/export/export.cpp
msgid "Release keystore incorrectly configured in the export preset."
-msgstr ""
+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 build template not installed in the project. Install it from the "
"Project menu."
-msgstr ""
+msgstr "תבנית בנייה לאנדרואיד לא מותקנת בפרוייקט. ההתקנה היא מתפריט המיזם."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
-msgstr ""
+msgstr "מפתח ציבורי לא חוקי להרחבת APK."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "שם שגוי."
+msgstr "שם חבילה לא חוקי:"
#: platform/android/export/export.cpp
msgid ""
"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
"project setting (changed in Godot 3.2.2).\n"
msgstr ""
+"מודול \"GodotPaymentV3\" לא חוקי נמצא בהגדרת המיזם ב-\"אנדרואיד/מודולים"
+"\" (שינוי בגודו 3.2.2).\n"
#: platform/android/export/export.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
-msgstr ""
+msgstr "חובה לאפשר ״שימוש בבניה מותאמת אישית״ כדי להשתמש בתוספים."
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
"\"."
-msgstr ""
+msgstr "\"דרגות של חופש\" תקף רק כאשר \"מצב Xr\" הוא \"Oculus Mobile VR\"."
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
-msgstr ""
+msgstr "\"Hand Tracking\" תקף רק כאשר \"מצב Xr\" הוא \"Oculus Mobile VR\"."
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
-msgstr ""
+msgstr "\"Focus Awareness\" תקף רק כאשר \"מצב Xr\" הוא \"Oculus Mobile VR\"."
#: 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 ""
+"מנסה לבנות מתבנית מותאמת אישית, אך לא קיים מידע על גירסת הבניה. נא להתקין "
+"מחדש מתפריט 'Project'."
#: 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 ""
+"חוסר התאמה בגירסת אנדרואיד:\n"
+" תבנית הותקנה: %s\n"
+" גרסת גודו: %s\n"
+"נא להתקין מחדש את תבנית בניית אנדרואיד מתפריט 'Project'."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "בניית מיזם אנדרואיד (gradle)"
#: platform/android/export/export.cpp
msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
+"בניית מיזם אנדרואיד נכשלה, ניתן לבדוק את הפלט לאיתור השגיאה.\n"
+"לחלופין, קיים ב- docs.godotengine.org תיעוד לבניית אנדרואיד."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "לא נוצר apk ב: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
-msgstr ""
+msgstr "מזהה חסר."
#: platform/iphone/export/export.cpp
msgid "The character '%s' is not allowed in Identifier."
-msgstr ""
+msgstr "התו '%s' אינו מותר במזהה."
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
-msgstr ""
+msgstr "לא צוין App Store Team ID - לא ניתן להגדיר את המיזם."
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Invalid Identifier:"
-msgstr "גודל הגופן שגוי."
+msgstr "מזהה לא חוקי:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
-msgstr ""
+msgstr "סמליל נדרש אינו מוגדר בהגדרות יצוא."
#: platform/javascript/export/export.cpp
msgid "Stop HTTP Server"
-msgstr ""
+msgstr "עצירת שרת HTTP"
#: platform/javascript/export/export.cpp
msgid "Run in Browser"
@@ -12240,74 +12243,74 @@ msgid "Using default boot splash image."
msgstr "נעשה שימוש בתמונת הפתיח כבררת מחדל."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package short name."
-msgstr "שם שגוי."
+msgstr "שם קצר של חבילה לא חוקי."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package unique name."
-msgstr "שם שגוי."
+msgstr "שם יחודי של חבילה לא חוקי."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package publisher display name."
-msgstr "שם שגוי."
+msgstr "שם תצוגה של מפרסם החבילה לא חוקי."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid product GUID."
-msgstr "שם שגוי."
+msgstr "GUID מוצר לא חוקי."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid publisher GUID."
-msgstr "נתיב שגוי."
+msgstr "GUID מפרסם לא חוקי."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid background color."
-msgstr "שם שגוי."
+msgstr "צבע רקע לא חוקי."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr ""
+msgstr "מידות תמונת לוגו חנות לא חוקיות (צריכות להיות 50x50)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
-msgstr ""
+msgstr "מידות תמונת לוגו מרובעות 44x44 לא חוקיות (צריכות להיות 44x44)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
-msgstr ""
+msgstr "מידות תמונת לוגו מרובעות 71x71 לא חוקיות (צריכות להיות 71x71)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
msgstr ""
+"מידות תמונת לוגו מרובעות בגודל 150x150 לא חוקיות (צריכות להיות 150x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
msgstr ""
+"מידות תמונת לוגו מרובעות בגודל 310x310 אינן חוקיות (צריכות להיות 310x310)."
#: platform/uwp/export/export.cpp
msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
-msgstr ""
+msgstr "מידות תמונת לוגו רחבה 310x150 לא חוקיות (צריכות להיות 310x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid splash screen image dimensions (should be 620x300)."
-msgstr ""
+msgstr "מידות תמונת פתיח לא חוקיות (צריכות להיות 620x300)."
#: 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 ""
+"יש ליצור או להגדיר משאב SpriteFrames במאפיין \"Frames\" כדי ש- "
+"AnimatedSprite יציג תמוניות."
#: 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 ""
+"מותר רק CanvasModulate גלוי אחד לכל סצנה (או סט מופעי סצינות). הראשון שנוצר "
+"יעבוד, ואילו השאר לא."
#: scene/2d/collision_object_2d.cpp
msgid ""
@@ -12315,6 +12318,9 @@ msgid ""
"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
"define its shape."
msgstr ""
+"למפרק זה אין צורה ולכן הוא לא יכול להתנגש או לקיים אינטראקציה עם אובייקטים "
+"אחרים.\n"
+"הוספת CollisionShape2D או CollisionPolygon2D כילד תגדיר את צורתו."
#: scene/2d/collision_polygon_2d.cpp
msgid ""
@@ -12322,6 +12328,9 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
+"CollisionPolygon2D משמש רק להספקת צורת התנגשות למפרק היורש מ-"
+"CollisionObject2D. השימוש בו הוא רק כילד של Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D וכו'."
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
@@ -12333,30 +12342,37 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
+"CollisionShape2D משמש רק להספקת צורת התנגשות למפרק היורש מ-"
+"CollisionObject2D. השימוש בו הוא רק כילד של Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D וכו'."
#: scene/2d/collision_shape_2d.cpp
msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
-msgstr ""
+msgstr "יש לספק צורה כדי ש-CollisionShape2D יתפקד. יש ליצור משאב צורה עבורו!"
#: scene/2d/collision_shape_2d.cpp
msgid ""
"Polygon-based shapes are not meant be used nor edited directly through the "
"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
msgstr ""
+"צורות מבוססות מצולע אינן מיועדות לשימוש או לעריכה ישירות דרך מפרק "
+"CollisionShape2D. במקום זאת יש להשתמש במפרק מסוג CollisionPolygon2D."
#: scene/2d/cpu_particles_2d.cpp
msgid ""
"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"הנפשת CPUParticles2D מחייבת שימוש ב-CanvasItemMaterial עם \"הנפשת חלקיקים\" "
+"מאופשרת."
#: scene/2d/light_2d.cpp
msgid ""
"A texture with the shape of the light must be supplied to the \"Texture\" "
"property."
-msgstr ""
+msgstr "יש לספק טקסטורה בצורת האור למאפיין \"טקסטורה\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -12372,12 +12388,16 @@ msgid ""
"A NavigationPolygon resource must be set or created for this node to work. "
"Please set a property or draw a polygon."
msgstr ""
+"יש להגדיר או ליצור משאב NavigationPolygon כדי שמפרק זה יעבוד. נא לקבוע "
+"מאפיין או לצייר מצולע."
#: scene/2d/navigation_polygon.cpp
msgid ""
"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
"node. It only provides navigation data."
msgstr ""
+"NavigationPolygonInstance חייב להיות ילד או נכד למפרק Navigation2D. הוא מספק "
+"רק נתוני ניווט."
#: scene/2d/parallax_layer.cpp
msgid ""
@@ -12391,6 +12411,9 @@ msgid ""
"Use the CPUParticles2D node instead. You can use the \"Convert to "
"CPUParticles\" option for this purpose."
msgstr ""
+"חלקיקים מבוססי GPU אינם נתמכים על-ידי מנהל ווידאו GLES2.\n"
+"השתמש בצומת CPUParticles2D במקום. למטרה זו האפשרות \"המר לחלקיקים של CPU\" "
+"קיימת."
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
@@ -12403,6 +12426,8 @@ msgid ""
"Particles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"הנפשת Particles2D מחייבת שימוש ב-CanvasItemMaterial עם \"הנפשת חלקיקים\" "
+"מאופשרת."
#: scene/2d/path_2d.cpp
msgid "PathFollow2D only works when set as a child of a Path2D node."
@@ -12414,23 +12439,26 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"שינויים בגודל ל-RigidBody2D (במצבי character או rigid) יבוטלו על ידי מנוע "
+"הפיזיקה בזמן ריצה.\n"
+"במקום זאת יש לשנות את גודל צורות ההתנגשות של הצאצאים."
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
-msgstr ""
+msgstr "מאפיין הנתיב חייב להצביע על מפרק Node2D חוקי כדי לעבוד."
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
-msgstr ""
+msgstr "שרשרת Bone2D זו אמורה להסתיים במפרק Skeleton2D."
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
-msgstr ""
+msgstr "Bone2D עובד רק עם Skeleton2D או Bone2D אחר כמפרק ההורה."
#: scene/2d/skeleton_2d.cpp
msgid ""
"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
-msgstr ""
+msgstr "לעצם זו אין תנוחת REST ראויה. עבור למפרק ה-Skeleton2D והגדר אחד."
#: scene/2d/tile_map.cpp
msgid ""
@@ -12438,44 +12466,45 @@ msgid ""
"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
"KinematicBody2D, etc. to give them a shape."
msgstr ""
+"TileMap עם שימוש בהורה מאופשר זקוק להורה CollisionObject2D כדי לתת לו צורות. "
+"אנא השתמש בו כצאצא של Area2D, StaticBody2D, RigidBody2D, KinematicBody2D "
+"וכו' כדי לתת להם צורה."
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
+"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
-#, fuzzy
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr "ל־ARVRCamera חייב להיות מפרק ARVROrigin כהורה שלו"
+msgstr "ההורה של ARVRController חייב להיות מפרק ARVROrigin."
#: 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 ""
+msgstr "מזהה הבקר אינו יכול להיות 0 או שבקר זה לא יהיה מחובר לבקר האמיתי."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ל־ARVRCamera חייב להיות מפרק ARVROrigin כהורה שלו"
+msgstr "ההורה של ARVRAnchor חייב להיות מפרק ARVROrigin."
#: 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 ""
+msgstr "מזהה העוגן אינו יכול להיות 0 או שעוגן זה לא יהיה מחובר לעוגן האמיתי."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin דורש מפרק צאצא מסוג ARVRCamera"
+msgstr "ARVROrigin דורש צאצא מסוג ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -12487,19 +12516,19 @@ msgstr "(זמן שנותר: %d:%02d שנ׳)"
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Meshes: "
-msgstr ""
+msgstr "מדפיס רשתות: "
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Lights:"
-msgstr ""
+msgstr "מדפיס תאורות:"
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
msgid "Finishing Plot"
-msgstr ""
+msgstr "מסיים הדפסה"
#: scene/3d/baked_lightmap.cpp
msgid "Lighting Meshes: "
-msgstr ""
+msgstr "רשתות תאורה: "
#: scene/3d/collision_object.cpp
msgid ""
@@ -12507,6 +12536,9 @@ msgid ""
"Consider adding a CollisionShape or CollisionPolygon as a child to define "
"its shape."
msgstr ""
+"למפרק זה אין צורה ולכן הוא לא יכול להתנגש או לקיים אינטראקציה עם אובייקטים "
+"אחרים.\n"
+"כדאי להוסיף CollisionShape2D או CollisionPolygon2D כצאצא כדי להגדיר צורה."
#: scene/3d/collision_polygon.cpp
msgid ""
@@ -12514,6 +12546,9 @@ msgid ""
"CollisionObject derived node. Please only use it as a child of Area, "
"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
msgstr ""
+"CollisionPolygon2D משמש רק להספקת צורת התנגשות למפרק היורש מ-"
+"CollisionObject2D. השימוש בו הוא רק כצאצא של Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D וכו'."
#: scene/3d/collision_polygon.cpp
msgid "An empty CollisionPolygon has no effect on collision."
@@ -12525,57 +12560,71 @@ msgid ""
"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
"KinematicBody, etc. to give them a shape."
msgstr ""
+"CollisionShape משמש רק להספקת צורת התנגשות למפרק היורש מ-CollisionObject2D. "
+"השימוש בו הוא רק כצאצא של Area, StaticBody, RigidBody, KinematicBody וכו'."
#: scene/3d/collision_shape.cpp
msgid ""
"A shape must be provided for CollisionShape to function. Please create a "
"shape resource for it."
-msgstr ""
+msgstr "יש לספק צורה כדי ש-CollisionShape יתפקד. יש ליצור משאב צורה עבורו."
#: scene/3d/collision_shape.cpp
msgid ""
"Plane shapes don't work well and will be removed in future versions. Please "
"don't use them."
msgstr ""
+"צורות מישוריות אינן פועלות היטב ויוסרו בגירסאות עתידיות. נא לא להשתמש בהן."
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
-msgstr ""
+msgstr "ConcavePolygonShape לא תומך ב- RigidBody במצב שאינו סטטי."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
-msgstr ""
+msgstr "שום דבר לא נראה כי לא הוקצאה רשת."
#: scene/3d/cpu_particles.cpp
msgid ""
"CPUParticles animation requires the usage of a SpatialMaterial whose "
"Billboard Mode is set to \"Particle Billboard\"."
msgstr ""
+"אנימציה של CPUParticles מחייבת שימוש ב-SpatialMaterial אשר מצב Billboard שלו "
+"מוגדר ל-\"Particle Billboard\"."
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
-msgstr ""
+msgstr "הדפסת רשתות"
#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
msgstr ""
+"מנהל הווידאו GLES2 אינו תומך ב- GIProbes.\n"
+"השתמש ב-BakedLightmap במקום."
+
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "SpotLight עם זווית רחבה מ-90 מעלות אינו יכול להטיל צללים."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
-msgstr ""
+msgstr "יש להגדיר או ליצור משאב NavigationMesh כדי שצומת זה יפעל."
#: scene/3d/navigation_mesh.cpp
msgid ""
"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
"It only provides navigation data."
msgstr ""
+"NavigationMeshInstance חייב להיות ילד או נכד למפרק Navigation. הוא מספק רק "
+"נתוני ניווט."
#: scene/3d/particles.cpp
msgid ""
@@ -12583,28 +12632,34 @@ msgid ""
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
"\" option for this purpose."
msgstr ""
+"חלקיקים מבוססי GPU אינם נתמכים על-ידי מנהל ווידאו GLES2.\n"
+"השתמש בצומת CPUParticles במקום. למטרה זו האפשרות \"המר לחלקיקים של CPU\" "
+"קיימת."
#: scene/3d/particles.cpp
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
-msgstr ""
+msgstr "שום דבר אינו גלוי כי רשתות לא הוקצו למעברי ההדפסה."
#: scene/3d/particles.cpp
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
+"אנימציה של חלקיקים מחייבת שימוש ב-SpatialMaterial אשר מצב Billboard שלו "
+"מוגדר ל-\"Particle Billboard\"."
#: scene/3d/path.cpp
-#, fuzzy
msgid "PathFollow only works when set as a child of a Path node."
-msgstr "PathFollow2D עובד רק כאשר הוא מוגדר כצאצא של מפרק Path2D."
+msgstr "PathFollow עובד רק כאשר הוא מוגדר כצאצא של מפרק Path."
#: scene/3d/path.cpp
msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
msgstr ""
+"ROTATION_ORIENTED של PathFollow דורש הפעלה של \"Up Vector\" במשאב העקומה של "
+"Path בהורה שלו."
#: scene/3d/physics_body.cpp
msgid ""
@@ -12612,16 +12667,21 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"שינויים בגודל ל-RigidBody (במצבי character או rigid) יבוטלו על ידי מנוע "
+"הפיזיקה בזמן ריצה.\n"
+"במקום זאת יש לשנות את גודל צורות ההתנגשות של הצאצאים."
#: scene/3d/remote_transform.cpp
msgid ""
"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
"derived node to work."
msgstr ""
+"המאפיין \"Remote Path\" חייב להפנות למפרק חוקי מסוג Spatial או יורש ממנו כדי "
+"לעבוד."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
-msgstr ""
+msgstr "תהיה התעלמות מגוף זה עד שתקבע רשת."
#: scene/3d/soft_body.cpp
msgid ""
@@ -12629,77 +12689,85 @@ msgid ""
"running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"שינויים בגודל ל-SoftBody יבוטלו על ידי מנוע הפיזיקה בזמן ריצה.\n"
+"במקום זאת יש לשנות את גודל צורות ההתנגשות של הצאצאים."
#: 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 ""
+"יש ליצור או להגדיר משאב SpriteFrames במאפיין \"Frames\" כדי ש-"
+"AnimatedSprite3D יציג תמוניות."
#: 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 ""
+"VehicleWheel משמש להספקת מערכת גלגלים ל-VehicleBody. יש להשתמש בו כצאצא של "
+"VehicleBody."
#: scene/3d/world_environment.cpp
msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment דורש שמאפיין \"Environment\" שלו יכיל סביבה כדי שתהיה השפעה "
+"גלויה."
#: scene/3d/world_environment.cpp
msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
-msgstr ""
+msgstr "רק WorldEnvironment אחד מותר לכל סצנה (או קבוצה של מופעי סצנות)."
#: 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 ""
+"ה-WorldEnvironment הזה לא פעיל. הוסף מצלמה (לסצנות תלת ממדיות) או הגדר את "
+"מצב הרקע של סביבה זו ל-Canvas (לסצינות דו-ממדיות)."
#: scene/animation/animation_blend_tree.cpp
msgid "On BlendTree node '%s', animation not found: '%s'"
-msgstr ""
+msgstr "במפרק 'BlendTree '%s, הנפשה לא נמצאה: '%s'"
#: scene/animation/animation_blend_tree.cpp
-#, fuzzy
msgid "Animation not found: '%s'"
-msgstr "משך ההנפשה (בשניות)."
+msgstr "הנפשה לא נמצאה: '%s'"
#: scene/animation/animation_tree.cpp
msgid "In node '%s', invalid animation: '%s'."
-msgstr ""
+msgstr "בצומת '%s', הנפשה לא חוקית: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Invalid animation: '%s'."
-msgstr "גודל הגופן שגוי."
+msgstr "הנפשה לא חוקית: '%s'."
#: scene/animation/animation_tree.cpp
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr ""
+msgstr "שום דבר לא מחובר לקלט '%s' של צומת '%s'."
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
-msgstr ""
+msgstr "לא נקבע שורש AnimationNode עבור הגרף."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
-msgstr ""
+msgstr "לא נקבע נתיב למפרק AnimationPlayer המכיל הנפשות."
#: scene/animation/animation_tree.cpp
msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
-msgstr ""
+msgstr "הנתיב שהוגדר ל-AnimationPlayer אינו מוביל למפרק AnimationPlayer."
#: scene/animation/animation_tree.cpp
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."
-msgstr ""
+msgstr "מפרק זה הוצא משימוש. יש להשתמש ב-AnimationTree במקום."
#: scene/gui/color_picker.cpp
msgid ""
@@ -12707,27 +12775,29 @@ msgid ""
"LMB: Set color\n"
"RMB: Remove preset"
msgstr ""
+"צבע: #%s\n"
+"לחצן עכבר שמאלי: קביעת צבע\n"
+"לחצן עכבר ימני: הסרת צבע שמור"
#: scene/gui/color_picker.cpp
msgid "Pick a color from the editor window."
-msgstr ""
+msgstr "בחירת צבע מחלון העורך."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
-msgstr ""
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
-msgstr ""
+msgstr "מעבר בין ערכים הקסדצימלים לערכי קוד."
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Add current color as a preset."
-msgstr "הוספת הצבע הנוכחי כערכה"
+msgstr "הוספת הצבע הנוכחי לערכת הצבעים."
#: scene/gui/container.cpp
msgid ""
@@ -12735,20 +12805,24 @@ msgid ""
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
+"המיכל בפני עצמו אינו משרת מטרה אלא אם כן סקריפט מגדיר את המיקום של צאצאיו.\n"
+"אם אין כוונה להוסיף סקריפט, יש להוסיף במקום זאת מפרק בקרה פשוט."
#: scene/gui/control.cpp
msgid ""
"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
msgstr ""
+"ה-Hint Tooltip לא יוצג כאשר מסנן העכבר של הבקר נקבע כ-\"Ignore\". כדי לפתור "
+"זאת, יש להגדיר את מסנן העכבר ל-\"Stop\" או \"Pass\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
-msgstr ""
+msgstr "אזהרה!"
#: scene/gui/dialogs.cpp
msgid "Please Confirm..."
-msgstr "נא לאמת…"
+msgstr "נא לאשר…"
#: scene/gui/popup.cpp
msgid ""
@@ -12756,10 +12830,12 @@ msgid ""
"functions. Making them visible for editing is fine, but they will hide upon "
"running."
msgstr ""
+"חלונות קופצים מוסתרים כברירת מחדל אלא אם תהיה קריאה ל-popup() או לאחת "
+"מפונקציות popup*(). החלונות יוצגו בזמן עריכה, אך יוסתרו בזמן ריצה."
#: scene/gui/range.cpp
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr ""
+msgstr "אם \"Exp Edit\" מאופשר, \"Min Value\" חייב להיות גדול מ-0."
#: scene/gui/scroll_container.cpp
msgid ""
@@ -12767,6 +12843,9 @@ msgid ""
"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
"minimum size manually."
msgstr ""
+"ScrollContainer מיועד לעבודה עם בקר צאצא יחיד.\n"
+"יש להשתמש במיכל כצאצא (VBox, HBox וכו'), או בבקר ולקבוע את הגודל המינימלי "
+"המותאם אישית באופן ידני."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -12777,6 +12856,8 @@ msgid ""
"Default Environment as specified in Project Settings (Rendering -> "
"Environment -> Default Environment) could not be loaded."
msgstr ""
+"לא היתה אפשרות לטעון את הסביבה שנקבעה כברירת המחדל בהגדרות המיזם (Rendering -"
+"> Environment -> Default Environment)."
#: scene/main/viewport.cpp
msgid ""
@@ -12785,41 +12866,52 @@ msgid ""
"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
"texture to some node for display."
msgstr ""
+"חלון תצוגה זה אינו מוגדר כיעד עיבוד. להצגת התוכן ישירות למסך, יש להפוך אותו "
+"לצאצא של בקר כדי שיקבל גודל. או להפוך אותו ל-RenderTarget ולשייך את המרקם "
+"הפנימי שלו למפרק כלשהו לתצוגה."
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "גודל חלון התצוגה חייב להיות גדול מ-0 על מנת להציג משהו."
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "גודל הגופן שגוי."
+msgstr "מקור לא תקין לתצוגה מקדימה."
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for shader."
-msgstr "גודל הגופן שגוי."
+msgstr "מקור לא תקין ל-shader."
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid comparison function for that type."
-msgstr "גודל הגופן שגוי."
+msgstr "פונקציית השוואה לא חוקית לסוג זה."
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
-msgstr ""
+msgstr "השמה לפונקציה."
#: servers/visual/shader_language.cpp
msgid "Assignment to uniform."
-msgstr ""
+msgstr "השמה ל-uniform."
#: servers/visual/shader_language.cpp
msgid "Varyings can only be assigned in vertex function."
-msgstr ""
+msgstr "ניתן להקצות שינויים רק בפונקצית vertex."
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "אי אפשר לשנות קבועים."
+
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "מערכת קבצים"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "בעת ייצוא או הטמעה, קובץ ההפעלה ינסה להתחבר לכתובת ה־IP של המחשב הזה "
+#~ "לצורך ניפוי שגיאות."
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "הסצנה הנוכחית מעולם לא נשמרה, נא לשמור אותה בטרם ההרצה."
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 70d7a4d6b3..3c8f54033a 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -528,6 +528,7 @@ msgid "Seconds"
msgstr "सेकंड"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "एफपीएस"
@@ -706,7 +707,7 @@ msgstr "पूंजीकरण मेल करे"
msgid "Whole Words"
msgstr "पूरे शब्द"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "बदले"
@@ -898,6 +899,11 @@ msgid "Signals"
msgstr "संकेत"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "फ़िल्टर फ़ाइलें..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "क्या आप सुनिश्चित हैं कि आप इस सिग्नल से सभी कनेक्शन हटाना चाहते हैं?"
@@ -935,7 +941,7 @@ msgid "Recent:"
msgstr "हाल ही में किया:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "खोज:"
@@ -1115,6 +1121,9 @@ msgstr "परियोजना के संस्थापक"
msgid "Lead Developer"
msgstr "प्रमुख डेवलपर"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "परियोजना प्रबंधक "
@@ -1136,6 +1145,16 @@ msgid "Gold Sponsors"
msgstr "गोल्ड प्रायोजक"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "रजत दाताओं"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "कांस्य दाताओं"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "मिनी प्रायोजक"
@@ -1609,16 +1628,17 @@ 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 "फाइलसिस्टेम और इंपोर्ट डोक्स"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "फ़ाइल"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "इंपोर्ट डॉक"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1880,7 +1900,7 @@ msgstr "डायरेक्टरिज & फ़ाइले:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "पूर्व दर्शन:"
@@ -2741,24 +2761,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"निर्यात या तैनाती करते समय, परिणामी निष्पादक इस कंप्यूटर के आईपी से जुड़ने का प्रयास करेगा "
-"ताकि डिबग किया जा सके।"
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "नेटवर्क एफएस के साथ छोटे तैनात"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"जब यह विकल्प सक्षम हो जाता है, तो निर्यात या तैनाती न्यूनतम निष्पादित उत्पादन करेगी।\n"
"नेटवर्क के ऊपर संपादक द्वारा परियोजना से फाइलसिस्टम उपलब्ध कराया जाएगा।\n"
@@ -2770,9 +2794,10 @@ msgid "Visible Collision Shapes"
msgstr "दृश्यमान टकराव आकार"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"यदि यह विकल्प चालू हो जाता है तो टकराव के आकार और रेकास्ट नोड्स (2डी और 3 डी के लिए) "
"चल रहे खेल पर दिखाई देंगे।"
@@ -2782,21 +2807,24 @@ msgid "Visible Navigation"
msgstr "दर्शनीय नेविगेशन"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr "यदि यह विकल्प चालू हो जाता है तो नेविगेशन मेशेस और बहुभुज चल रहे खेल पर दिखाई देंगे।"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "सिंक सीन बदलता है"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"जब इस विकल्प को चालू किया जाता है, तो संपादक में दृश्य में किए गए किसी भी परिवर्तन को "
"चल रहे खेल में दोहराया जाएगा।\n"
@@ -2804,15 +2832,17 @@ msgstr ""
"कुशल होता है।"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "सिंक स्क्रिप्ट परिवर्तन"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"जब यह विकल्प चालू हो जाएगा, तो सहेजी गई किसी भी स्क्रिप्ट को चल रहे गेम पर फिर से लोड "
"किया जाएगा।\n"
@@ -2876,7 +2906,7 @@ msgstr "मदद"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "ढूंढें"
@@ -3289,9 +3319,11 @@ msgid "Add Key/Value Pair"
msgstr "कुंजी/मूल्य जोड़ी जोड़ें"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"इस मंच के लिए कोई रननयोग्य निर्यात पूर्व निर्धारित नहीं मिला।\n"
"कृपया निर्यात मेनू में एक रननेबल प्रीसेट जोड़ें।"
@@ -5022,7 +5054,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7642,7 +7674,7 @@ msgid "New Animation"
msgstr "एनिमेशन लूप"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9675,6 +9707,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "प्रोजेक्ट मैनेजर"
@@ -10108,11 +10141,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "बदले"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10158,7 +10196,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10217,7 +10255,7 @@ msgid "Reset"
msgstr "रीसेट आकार"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12194,6 +12232,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12450,6 +12493,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "फाइलसिस्टेम और इंपोर्ट डोक्स"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "निर्यात या तैनाती करते समय, परिणामी निष्पादक इस कंप्यूटर के आईपी से जुड़ने का प्रयास "
+#~ "करेगा ताकि डिबग किया जा सके।"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "वर्तमान दृश्य कभी नहीं बचाया गया था, कृपया इसे चलाने से पहले बचाने के लिए ।"
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index a515a912b0..ff82f3aafc 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -512,6 +512,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -691,7 +692,7 @@ msgstr ""
msgid "Whole Words"
msgstr "Cijele riječi"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Zamijeni"
@@ -884,6 +885,11 @@ msgid "Signals"
msgstr "Signali"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Iz signala:"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Jesi li siguran da želiš ukloniti sve veze s ovog signala?"
@@ -921,7 +927,7 @@ msgid "Recent:"
msgstr "Nedavno:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Pretraga:"
@@ -1102,6 +1108,9 @@ msgstr "Osnivači projekta"
msgid "Lead Developer"
msgstr "Glavni razvijatelj"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projektni menadžer "
@@ -1123,6 +1132,16 @@ msgid "Gold Sponsors"
msgstr "Zlatni sponzori"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Srebrni donatori"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Brončani donatori"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini sponzori"
@@ -1587,15 +1606,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1858,7 +1877,7 @@ msgstr "Direktoriji i datoteke:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Pregled:"
@@ -2687,22 +2706,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2711,8 +2734,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2721,32 +2744,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2806,7 +2829,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3209,7 +3232,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4941,7 +4965,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7536,7 +7560,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9529,6 +9553,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9959,11 +9984,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Zamijeni"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10009,7 +10039,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10067,7 +10097,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12017,6 +12047,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index c6828cc7d3..cac984d6d6 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -11,11 +11,12 @@
# Máté Lugosi <mate.lugosi@gmail.com>, 2019.
# sztrovacsek <magadeve@gmail.com>, 2019.
# Ács Zoltán <acszoltan111@gmail.com>, 2020.
+# cefrebevalo <szmarci711@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
"Last-Translator: Ács Zoltán <acszoltan111@gmail.com>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/hu/>\n"
@@ -24,18 +25,18 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-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 ""
-"Érvénytelen típus argumentum a convert()-hez használjon TYPE_* konstansokat."
+"Érvénytelen típusargumentum a convert()-hez használjon TYPE_* konstansokat."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#, fuzzy
msgid "Expected a string of length 1 (a character)."
-msgstr "Egy karakter hosszúságú string-et várt."
+msgstr "Egy hosszúságú karaktersorozat szükséges."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -57,17 +58,15 @@ msgstr "Érvénytelen operandusok az %s, %s és %s operátorhoz."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr "Érvénytelen %s típusú index a %s alap típushoz."
+msgstr ""
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
msgstr "Érvénytelen nevezett index '%s' %s alaptípushoz"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid arguments to construct '%s'"
msgstr ""
-"Érvénytelen típus argumentum a convert()-hez használjon TYPE_* konstansokat."
#: core/math/expression.cpp
msgid "On call to '%s':"
@@ -123,15 +122,15 @@ msgstr "Érték:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr "Kulcs Beszúrása"
+msgstr "Kulcs beszúrása"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr "Kiválasztott elem(ek) megkettőzése"
+msgstr "Kiválasztott kulcs(ok) megkettőzése"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr "Kiválasztott kulcsok törlése"
+msgstr "Kiválasztott kulcs(ok) törlése"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
@@ -139,7 +138,7 @@ msgstr "Bézier pont hozzáadása"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr "Bézier pont mozgatása"
+msgstr "Bézier pontok áthelyezése"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -147,9 +146,10 @@ 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ése"
+msgstr "Animáció kulcsok törlése"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Anim Change Keyframe Time"
msgstr "Animáció kulcsképkocka idő változtatás"
@@ -196,7 +196,7 @@ msgstr "Animáció hívás változtatás"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr "Animáció hosszának megváltoztatása"
+msgstr "Animáció hosszának változtatása"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -204,14 +204,12 @@ msgid "Change Animation Loop"
msgstr "Animációs ciklus változtatása"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Property Track"
-msgstr "Tulajdonság Követés"
+msgstr "Tulajdonságkövetés"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "3D Transform Track"
-msgstr "UV Térkép Transzformálása"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
@@ -219,16 +217,16 @@ msgstr "Hívás módszer követése"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
-msgstr "Bezier Görbe Nyomvonal"
+msgstr "Bézier görbe nyomvonal"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Audio Playback Track"
msgstr "Hang lejátszás követése"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Playback Track"
-msgstr "Animáció lejátszásának leállítása. (S)"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
@@ -239,33 +237,33 @@ msgid "Animation length (seconds)"
msgstr "Animáció hossza (másodpercben)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr "Nyomvonal hozzáadása"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
-msgstr "Animáció ismételtetése"
+msgstr "Animáció ismétlése"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Functions:"
-msgstr "Funkciók:"
+msgstr "Függvények:"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Audio Clips:"
-msgstr ""
+msgstr "Audió klipek:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "Animáció klipek:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Track Path"
-msgstr "Tömb Értékének Megváltoztatása"
+msgstr ""
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Toggle this track on/off."
msgstr "A sáv ki/be kapcsolása."
@@ -275,7 +273,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
-msgstr "Interpoláció mód"
+msgstr "Interpolációs mód"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
@@ -288,12 +286,11 @@ msgstr "Kiválasztott nyomvonal eltávolítása."
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr "Idő (mp):"
+msgstr "Idő (mp): "
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Toggle Track Enabled"
-msgstr "Doppler engedélyezése"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -335,32 +332,27 @@ msgstr ""
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Kulcs Beszúrása"
+msgstr "Kulcs beszúrása"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "Animáció kulcsok megkettőzése"
+msgstr "Kulcs(ok) megkettőzése"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Key(s)"
-msgstr "Animáció kulcs törlés"
+msgstr "Kulcs(ok) törlése"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Update Mode"
-msgstr "Animáció Nevének Megváltoztatása:"
+msgstr "Animáció frissítés módjának megváltoztatása"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Interpolation Mode"
-msgstr "Animáció Node"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Loop Mode"
-msgstr "Animáció hurok változtatás"
+msgstr "Animáció hurok mód változtatása"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -368,11 +360,11 @@ msgstr "Animáció nyomvonal eltávolítás"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr "Létrehoz ÚJ nyomvonalat %s -hez és beilleszti a kulcsot?"
+msgstr "ÚJ nyomvonalat hoz létre a következőhöz: %s, és beszúrja a kulcsot?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "Létrehoz %d ÚJ nyomvonalat és beilleszti a kulcsokat?"
+msgstr "Létrehoz %d ÚJ nyomvonalat és beszúrja a kulcsokat?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -388,19 +380,20 @@ msgstr "Létrehozás"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
-msgstr "Animáció beillesztés"
+msgstr "Animáció beszúrása"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr ""
+msgstr "Az AnimationPlayer nem tudja animálni önmagát, csak más játékosokat."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
-msgstr "Animáció létrehozás és beillesztés"
+msgstr "Animáció létrehozása és beillesztése"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr "Animáció nyomvonal és kulcs beillesztés"
+msgstr "Animáció nyomvonal és kulcs beszúrása"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
@@ -411,9 +404,8 @@ msgid "Change Animation Step"
msgstr "Animáció léptékének megváltoztatása"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Rearrange Tracks"
-msgstr "AutoLoad-ok Átrendezése"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
@@ -444,9 +436,8 @@ msgid "Invalid track for Bezier (no suitable sub-properties)"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
@@ -457,43 +448,40 @@ msgid "Track is not of type Spatial, can't insert key"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Transform Track Key"
-msgstr "UV Térkép Transzformálása"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr "Nyomvonal kulcs hozzáadása"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "Animáció nyomvonal és kulcs beillesztés"
+msgstr "Metódus nyomvonal kulcs beillesztése"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
-msgstr ""
+msgstr "A metódus nem található az objektumban: "
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Anim Move Keys"
-msgstr "Animáció kulcs mozgatás"
+msgstr "Animáció kulcsok mozgatása"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Clipboard is empty"
-msgstr "Az erőforrás vágólap üres!"
+msgstr "A vágólap üres"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
-msgstr "Paraméterek Beillesztése"
+msgstr "Nyomvonalak beillesztése"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Anim Scale Keys"
msgstr "Animáció kulcsok nyújtás"
@@ -517,14 +505,13 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "Figyelmeztetés: Importált animáció szerkesztése"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select an AnimationPlayer node to create and edit animations."
msgstr ""
-"Válasszon egy AnimationPlayer-t a Jelenetfából, hogy animációkat "
-"szerkeszthessen."
+"Válasszon egy AnimationPlayer node-ot az animációk létrehozásához és "
+"szerkesztéséhez."
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -535,22 +522,21 @@ msgid "Group tracks by node or display them as plain list."
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "Illesztés"
+msgstr "Illesztés:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation step value."
-msgstr "Az animációs fa érvényes."
+msgstr "Animáció lépés értéke."
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "Másodperc"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
-msgstr ""
+msgstr "FPS"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -563,18 +549,16 @@ msgid "Edit"
msgstr "Szerkesztés"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation properties."
-msgstr "AnimációFa"
+msgstr "Animáció tulajdonságok."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Copy Tracks"
-msgstr "Paraméterek Másolása"
+msgstr "Nyomvonalak másolása"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
-msgstr "Kiválasztás átméretezés"
+msgstr "Kijelölés átméretezése"
#: editor/animation_track_editor.cpp
msgid "Scale From Cursor"
@@ -582,16 +566,15 @@ msgstr "Átméretezés a kurzortól"
#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Duplicate Selection"
-msgstr "Kiválasztás megkettőzés"
+msgstr "Kijelölés megkettőzése"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "Áthelyezettek megkettőzés"
+msgstr "Áthelyezettek megkettőzése"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "Kijelölés Középre"
+msgstr "Kijelölés törlése"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -599,21 +582,20 @@ msgid "Go to Next Step"
msgstr "Ugrás a következő lépésre"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Previous Step"
msgstr "Ugrás az előző lépésre"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr "Animáció optimalizálás"
+msgstr "Animáció optimalizálása"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr "Animáció megtisztítás"
+msgstr "Animáció tisztítása"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "Válassza ki az animálandó node-ot:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
@@ -621,19 +603,19 @@ msgstr "Bézier görbék használata"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
-msgstr "Animáció Optimalizáló"
+msgstr "Animáció optimalizáló"
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
-msgstr "Max. Lineáris Hiba:"
+msgstr "Maximum lineáris hiba:"
#: editor/animation_track_editor.cpp
msgid "Max. Angular Error:"
-msgstr "Max. Szög Hiba:"
+msgstr "Maximum szög hiba:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr "Max. Optimalizálható Szög:"
+msgstr "Maximum optimalizálható szög:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
@@ -664,9 +646,8 @@ msgid "Scale Ratio:"
msgstr "Méretezési arány:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "Átmenet beállítása erre:"
+msgstr "Másolandó nyomvonalak kiválasztása"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -678,14 +659,12 @@ msgid "Copy"
msgstr "Másolás"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "Kiválasztó Mód"
+msgstr "Összes/semmi kijelölése"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr ""
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -697,57 +676,56 @@ msgstr ""
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "Tömb Átméretezése"
+msgstr "Tömb átméretezése"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr "Tömb Értéktípusának Megváltoztatása"
+msgstr "Tömb értéktípusának megváltoztatása"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr "Tömb Értékének Megváltoztatása"
+msgstr "Tömb értékének megváltoztatása"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr "Ugrás Sorra"
+msgstr "Ugrás sorra"
#: editor/code_editor.cpp
msgid "Line Number:"
msgstr "Sorszám:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "Csere..."
+msgstr "%d lecserélve."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "%d egyezés."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "Nincs Találat"
+msgstr "%d egyezés."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr "Pontos Egyezés"
+msgstr "Nagybetűérzékeny"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
-msgstr "Egész Szavak"
+msgstr "Egész szavak"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
-msgstr "Lecserélés"
+msgstr "Csere"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Mind Lecserélése"
+msgstr "Összes cseréje"
#: editor/code_editor.cpp
+#, fuzzy
msgid "Selection Only"
-msgstr "Csak Kiválsztás"
+msgstr "Csak a kijelölés"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
@@ -755,8 +733,9 @@ msgid "Standard"
msgstr ""
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Toggle Scripts Panel"
-msgstr "Szkript Panel Megjelenítése"
+msgstr "Szkript panel váltása"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -772,54 +751,47 @@ msgstr "Kicsinyítés"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Nagyítás Visszaállítása"
+msgstr "Nagyítás visszaállítása"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr ""
+msgstr "Figyelmeztetések"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr ""
+msgstr "Sor és oszlopszámok."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "Nevezze meg a metódust a cél Node-ban!"
+msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method name must be a valid identifier."
-msgstr "Nevezze meg a metódust a cél Node-ban!"
+msgstr "A metódusnévnek érvényes azonosítónak kell lennie."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"Nem található a cél metódus! Nevezzen meg egy érvényes metódust, vagy "
-"csatoljon egy szkriptet a cél Node-hoz."
+"Nem található a célmetódus! Nevezzen meg egy érvényes metódust, vagy "
+"csatoljon egy szkriptet a cél node-hoz."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Node:"
-msgstr "Csatlakoztatás Node-hoz:"
+msgstr "Csatlakoztatás node-hoz:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "Nem lehet csatlakozni a kiszolgálóhoz:"
+msgstr "Csatlakoztatás szkripthez:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "Jelzések:"
+msgstr "Jelzésből:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Scene does not contain any script."
-msgstr "A Node nem tartalmaz geometriát."
+msgstr "A jelenet nem tartalmaz szkriptet."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -840,21 +812,19 @@ msgstr "Eltávolítás"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "További Meghívási Argumentum Hozzáadása:"
+msgstr "További meghívási argumentum hozzáadása:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr "További Meghívási Argumentumok:"
+msgstr "További hívási argumentumok:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "Objektumtulajdonságok."
+msgstr "Fogadó metódus:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "Illesztési beállítások"
+msgstr "Speciális"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -871,12 +841,11 @@ msgstr "Egyszeri"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr ""
+msgstr "Az első kibocsátás után lekapcsolja a jelzést."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Cannot connect signal"
-msgstr "Csatlakoztató Jelzés:"
+msgstr "Nem lehet csatlakoztatni a jelet"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -897,26 +866,24 @@ msgid "Connect"
msgstr "Csatlakoztatás"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Jelzések:"
+msgstr "Jelzés:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr "'%s' Csatlakoztatása '%s'-hez"
+msgstr "'%s' csatlakoztatása ehhez: '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr "'%s' Lecsatlakoztatása '%s'-ról"
+msgstr "'%s' leválasztása erről: '%s'"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect all from signal: '%s'"
-msgstr "'%s' Lecsatlakoztatása '%s'-ról"
+msgstr "Az összes leválasztása a jelzésről: '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
-msgstr "Kapcsolás..."
+msgstr "Csatlakoztatás..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -924,45 +891,45 @@ msgid "Disconnect"
msgstr "Leválasztás"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect a Signal to a Method"
-msgstr "Csatlakoztató Jelzés:"
+msgstr "Jelzés csatlakoztatása metódushoz"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit Connection:"
-msgstr "Kapcsolathiba"
+msgstr "Kapcsolat szerkesztése:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
-msgstr ""
+msgstr "Biztosan eltávolítja az összes kapcsolatot a(z) \"%s\" jelzésről?"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
msgstr "Jelzések"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Csempék szűrése"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
-msgstr ""
+msgstr "Biztosan eltávolítja az összes kapcsolatot erről a jelzésről?"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect All"
-msgstr "Szétkapcsol"
+msgstr "Összes lecsatlakoztatása"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit..."
-msgstr "Szerkesztés"
+msgstr "Szerkesztés..."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Go To Method"
-msgstr "Metódusok"
+msgstr "Ugrás metódusra"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr "%s Típusának Megváltoztatása"
+msgstr "%s típusának megváltoztatása"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
@@ -970,7 +937,7 @@ msgstr "Változtatás"
#: editor/create_dialog.cpp
msgid "Create New %s"
-msgstr "Új %s Létrehozása"
+msgstr "Új %s létrehozása"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
@@ -979,10 +946,10 @@ msgstr "Kedvencek:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
-msgstr "Legutolsó:"
+msgstr "Legutóbbi:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Keresés:"
@@ -991,7 +958,7 @@ msgstr "Keresés:"
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Matches:"
-msgstr "Találatok:"
+msgstr "Egyezések:"
#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
#: editor/plugin_config_dialog.cpp
@@ -1003,29 +970,27 @@ msgstr "Leírás:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr "Csere Keresése:"
+msgstr "Csere keresése:"
#: editor/dependency_editor.cpp
msgid "Dependencies For:"
msgstr "Függőségek:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Scene '%s' is currently being edited.\n"
"Changes will only take effect when reloaded."
msgstr ""
-"'%s' Scene éppen szerkesztés alatt áll.\n"
+"'%s' jelenet éppen szerkesztés alatt áll.\n"
"A változások újratöltés után lépnek érvénybe."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
msgstr ""
-"'%s' forrás éppen használatban van.\n"
-"A változtatások akkor lépnek életbe, ha a forrást újratölti."
+"A(z) '%s' forrás éppen használatban van.\n"
+"A változtatások újratöltéskor lépnek életbe."
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -1072,7 +1037,6 @@ msgid "Owners Of:"
msgstr "Tulajdonosai:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
msgstr "Eltávolítja a kiválasztott fájlokat a projektből? (nem visszavonható)"
@@ -1094,9 +1058,8 @@ msgid "Error loading:"
msgstr "Hiba betöltéskor:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Load failed due to missing dependencies:"
-msgstr "A Jelenetet nem sikerült betölteni a hiányzó függőségek miatt:"
+msgstr "A betöltés nem sikerült a hiányzó függőségek miatt:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
@@ -1119,9 +1082,8 @@ msgid "Permanently delete %d item(s)? (No undo!)"
msgstr "Véglegesen törlöl %d elemet? (Nem visszavonható!)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Show Dependencies"
-msgstr "Függőségek"
+msgstr "Függőségek megjelenítése"
#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
@@ -1167,6 +1129,9 @@ msgstr "Projekt Alapítói"
msgid "Lead Developer"
msgstr "Vezető Fejlesztő"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projekt Kezelő "
@@ -1188,6 +1153,14 @@ msgid "Gold Sponsors"
msgstr "Arany Szponzorok"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Ezüst adományozók"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Bronz adományozók"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Szponzorok"
@@ -1212,9 +1185,8 @@ msgid "License"
msgstr "Licenc"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
-msgstr "Harmadik Fél Engedély"
+msgstr "Harmadik féltől származó licencek"
#: editor/editor_about.cpp
#, fuzzy
@@ -1242,14 +1214,12 @@ msgid "Licenses"
msgstr "Licencek"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file, not in ZIP format."
-msgstr "Hiba a csomagfájl megnyitása során, nem zip formátumú."
+msgstr "Hiba a csomagfájl megnyitása során, nem ZIP formátumú."
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (Already Exists)"
-msgstr "Már létezik '%s' AutoLoad!"
+msgstr "'%s' (már létezik)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
@@ -1257,17 +1227,15 @@ msgstr "Eszközök Kicsomagolása"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "A következő fájlokat nem sikerült kibontani a csomagból:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
-msgstr "%d további fájl"
+msgstr "És további %s fájl."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Package installed successfully!"
-msgstr "A Csomag Telepítése Sikeresen Megtörtént!"
+msgstr "A csomag telepítése sikeres volt!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -1275,9 +1243,8 @@ msgid "Success!"
msgstr "Siker!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "Tartalom:"
+msgstr "Csomag tartalma:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1332,9 +1299,8 @@ msgid "Delete Bus Effect"
msgstr "Busz Effektus Törlése"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Drag & drop to rearrange."
-msgstr "Hangbusz, Húzd és Vidd az átrendezéshez."
+msgstr "Az átrendezéshez húzza át."
#: editor/editor_audio_buses.cpp
msgid "Solo"
@@ -1407,7 +1373,7 @@ msgstr "Hangbusz Elrendezés Megnyitása"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr ""
+msgstr "Nincs '%s' fájl."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
@@ -1418,18 +1384,16 @@ msgid "Invalid file, not an audio bus layout."
msgstr "Érvénytelen fájl, nem egy hangbusz elrendezés."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "Hiba TileSet mentésekor!"
+msgstr "Hiba a fájl mentésekor: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
msgstr "Busz Hozzáadása"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Add a new Audio Bus to this layout."
-msgstr "Hangbusz Elrendezés Mentése Másként..."
+msgstr "Új hangbusz hozzáadása ehhez az elrendezéshez."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1470,24 +1434,21 @@ msgid "Valid characters:"
msgstr "Érvényes karakterek:"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing engine class name."
-msgstr "Érvénytelen név. Nem ütközhet egy már meglévő motor osztálynévvel."
+msgstr "Nem ütközhet egy már meglévő játékmotor-osztálynévvel."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
msgstr "Érvénytelen név. Nem ütközhet egy már meglévő beépített típusnévvel."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
msgstr ""
"Érvénytelen név. Nem ütközhet egy már meglévő globális konstans névvel."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "A kulcsszó nem használható automatikus betöltési névként."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
@@ -1519,7 +1480,7 @@ msgstr "AutoLoad-ok Átrendezése"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr ""
+msgstr "Nem lehet hozzáadni az automatikus betöltést:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1571,9 +1532,8 @@ msgid "[unsaved]"
msgstr "[nincs mentve]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
-msgstr "Válasszon egy alap könyvtárat először"
+msgstr "Először válassza ki az alapkönyvtárat."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1607,7 +1567,7 @@ msgstr "Tároló Fájl:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "Nem található export sablon a várt útvonalon:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1636,15 +1596,14 @@ 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
-#, fuzzy
msgid "Custom debug template not found."
-msgstr "Sablon fájl nem található:"
+msgstr "Az egyéni hibakeresési sablon nem található."
#: 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 ""
+msgstr "Az egyéni kiadási sablon nem található."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
@@ -1655,119 +1614,107 @@ 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 "Szerkesztő"
+msgstr "3D szerkesztő"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "Szkript Szerkesztő Megnyitása"
+msgstr "Szkript szerkesztő"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Asset Library"
-msgstr "Eszköz Könyvtár Megnyitása"
+msgstr "Eszköz könyvtár"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
-msgstr ""
+msgstr "Jelenetfa szerkesztése"
#: editor/editor_feature_profile.cpp
-#, fuzzy
-msgid "Import Dock"
-msgstr "Importálás"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
-msgstr "Mozgás Mód"
+msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "Fájlrendszer"
#: editor/editor_feature_profile.cpp
-#, fuzzy
+msgid "Import Dock"
+msgstr "Dock importálása"
+
+#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
-msgstr "Mind Lecserélése"
+msgstr "Törli a(z) '%s' profilt? (nem visszavonható)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
msgstr ""
+"A profilnak érvényes fájlnévnek kell lennie, és nem tartalmazhatja a \".\" "
+"karaktert"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Profile with this name already exists."
-msgstr "Egy fájl vagy mappa már létezik a megadott névvel."
+msgstr "Ilyen nevű profil már létezik."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(A szerkesztő letiltva, a tulajdonságok letiltva)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Properties Disabled)"
-msgstr "Tulajdonságok"
+msgstr "(A tulajdonságok le vannak tiltva)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "Tiltva"
+msgstr "(A szerkesztő le van tiltva)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "Leírás:"
+msgstr "Osztály beállítások:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enable Contextual Editor"
-msgstr "Következő Szerkesztő Megnyitása"
+msgstr "Környezetfüggő szerkesztő engedélyezése"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Properties:"
-msgstr "Tulajdonságok"
+msgstr "Engedélyezett tulajdonságok:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
-msgstr ""
+msgstr "Engedélyezett funkciók:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Classes:"
-msgstr "Osztályok Keresése"
+msgstr "Engedélyezett osztályok:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "A(z) '%s' fájl formátuma érvénytelen, az importálás megszakítva."
#: editor/editor_feature_profile.cpp
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
+"A (z) '%s' profil már létezik. Importálás előtt először távolítsa el azt, "
+"importálás megszakítva."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "Hiba TileSet mentésekor!"
+msgstr "Hiba történt a profil útvonalba mentése során: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "Nincs beállítva"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Jelenlegi Verzió:"
+msgstr "Jelenlegi profil:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "Jelenlegi:"
+msgstr "Tegye jelenlegivé"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1785,44 +1732,36 @@ msgid "Export"
msgstr "Exportálás"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Tulajdonságok"
+msgstr "Elérhető profilok:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options"
-msgstr "Leírás"
+msgstr "Osztály beállításai"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "New profile name:"
-msgstr "Új név:"
+msgstr "Új profilnév:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase Profile"
-msgstr "Jobb Egérgomb: Pont Törlése."
+msgstr "Profil törlése"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Godot Feature Profile"
-msgstr "Export Sablonok Kezelése"
+msgstr "Godot funkcióprofil"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Import Profile(s)"
-msgstr "%d további fájl"
+msgstr "Profil(ok) importálása"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Export Profile"
-msgstr "Projekt Exportálása"
+msgstr "Profil exportálása"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Manage Editor Feature Profiles"
-msgstr "Export Sablonok Kezelése"
+msgstr "A szerkesztő funkcióprofiljainak kezelése"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1833,24 +1772,21 @@ msgid "File Exists, Overwrite?"
msgstr "Fájl Létezik, Felülírja?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select This Folder"
-msgstr "Aktuális Mappa Kiválasztása"
+msgstr "Válassza ezt a mappát"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
msgstr "Útvonal másolása"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "Mutat Fájlkezelőben"
+msgstr "Megnyitás a Fájlkezelőben"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
-msgstr "Mutat Fájlkezelőben"
+msgstr "Megjelenítés a Fájlkezelőben"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
@@ -1910,67 +1846,60 @@ msgstr "Ugrás Fel"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "Rejtett Fájlok Megjelenítése"
+msgstr ""
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "Kedvenc Kapcsolása"
+msgstr ""
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr "Mód Váltása"
+msgstr "Mód váltása"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "Elérési Út Fókuszálása"
+msgstr ""
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "Kedvenc Felfelé Mozgatása"
+msgstr "Kedvenc fentebb helyezése"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr "Kedvenc Lefelé Mozgatása"
+msgstr "Kedvenc lentebb helyezése"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "Ugrás a szülőmappába"
+msgstr "Ugrás az előző mappára."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "Ugrás a szülőmappába"
+msgstr "Ugrás a következő mappára."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
-msgstr "Ugrás a szülőmappába"
+msgstr "Lépjen a szülőmappába."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "Osztályok Keresése"
+msgstr "Fájlok frissítése."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "(Un)favorite current folder."
-msgstr "Nem sikerült létrehozni a mappát."
+msgstr "Jelenlegi mappa kedvenccé tétele/eltávolítása a kedvencek közül."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Toggle the visibility of hidden files."
-msgstr "Rejtett Fájlok Megjelenítése"
+msgstr "A rejtett fájlok láthatóságának ki- és bekapcsolása."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
#, fuzzy
msgid "View items as a grid of thumbnails."
-msgstr "Elemek kirajzolása indexképek rácsába"
+msgstr "Az elemek megtekintése bélyegkép-rácsként."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a list."
-msgstr "Elemek listázása"
+msgstr "Elemek megtekintése listaként."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
@@ -1978,7 +1907,7 @@ msgstr "Könyvtárak és Fájlok:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Előnézet:"
@@ -2022,14 +1951,12 @@ msgid "Inherited by:"
msgstr "Őt örökli:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Leírás:"
+msgstr "Leírás"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "Online Oktatóanyagok:"
+msgstr "Online oktatóanyagok"
#: editor/editor_help.cpp
msgid "Properties"
@@ -2037,21 +1964,19 @@ msgstr "Tulajdonságok"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "felülírja:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "Alapértelmezett"
+msgstr "alapértelmezett:"
#: editor/editor_help.cpp
msgid "Methods"
msgstr "Metódusok"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Theme Properties"
-msgstr "Tulajdonságok"
+msgstr "Téma tulajdonságai"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2062,14 +1987,12 @@ msgid "Constants"
msgstr "Konstansok"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "Tulajdonság Leírása:"
+msgstr "Tulajdonságleírások"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "Érték:"
+msgstr "(érték)"
#: editor/editor_help.cpp
msgid ""
@@ -2080,9 +2003,8 @@ msgstr ""
"[color=$color][url=$url]hozzájárul eggyel[/url][/color]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "Metódus Leírás:"
+msgstr "Metódusleírások"
#: editor/editor_help.cpp
msgid ""
@@ -2095,106 +2017,92 @@ msgstr ""
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Keresés Súgóban"
+msgstr "Keresés a súgóban"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
msgstr "Pontos Egyezés"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "Segítők Megjelenítése"
+msgstr "Hierarchia megjelenítése"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Display All"
-msgstr "Mind Lecserélése"
+msgstr "Az összes megjelenítése"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Classes Only"
-msgstr "Osztályok"
+msgstr "Csak osztályok"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Methods Only"
-msgstr "Metódusok"
+msgstr "Csak metódusok"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "Jelzések"
+msgstr "Csak jelzések"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Constants Only"
-msgstr "Konstansok"
+msgstr "Csak konstansok"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Properties Only"
-msgstr "Tulajdonságok"
+msgstr "Csak tulajdonságok"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Properties Only"
-msgstr "Tulajdonságok"
+msgstr "Csak tématulajdonságok"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Member Type"
-msgstr "Tagok"
+msgstr "Tag típusa"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Class"
-msgstr "Osztály:"
+msgstr "Osztály"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "Metódusok"
+msgstr "Metódus"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "Jelzések"
+msgstr "Jelzés"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
msgstr "Állandó"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "Tulajdonságok"
+msgstr "Tulajdonság"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "Tulajdonságok"
+msgstr "Téma tulajdonság"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "Tulajdonság:"
#: editor/editor_inspector.cpp
+#, fuzzy
msgid "Set"
-msgstr ""
+msgstr "Beállítás"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "Többszörös beállítása:"
#: editor/editor_log.cpp
msgid "Output:"
msgstr "Kimenet:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "Kiválasztás eltávolítás"
+msgstr "Kijelölés másolása"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2208,7 +2116,7 @@ msgstr "Töröl"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "Kimenet Törlése"
+msgstr "Kimenet törlése"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
@@ -2217,22 +2125,20 @@ msgstr "Leállítás"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
-#, fuzzy
msgid "Start"
-msgstr "Start!"
+msgstr "Start"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
-msgstr "Letöltés"
+msgstr "Le"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "Fel"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2240,27 +2146,27 @@ msgstr "Node"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "Bejövő RPC"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "Bejövő RSET"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "Kimenő RPC"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "Kimenő RSET"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "Új ablak"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "Az importált erőforrások nem menthetők."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
@@ -2276,6 +2182,8 @@ msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
msgstr ""
+"Ezt az erőforrást nem menthető, mert nem tartozik a szerkesztett jelenethez. "
+"Először tegye egyedivé."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -2296,6 +2204,7 @@ msgstr "Hiba történt mentés közben."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
msgstr ""
+"A(z) '%s' nem nyitható meg. Lehet, hogy a fájlt áthelyezték vagy törölték."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
@@ -2345,7 +2254,7 @@ msgstr ""
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "Nem lehet felülírni a még nyitott jelenetet!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -2392,14 +2301,13 @@ msgstr ""
"jobban megértse ezt a munkafolyamatot."
#: 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 ""
-"Ez az erőforrás egy olyan Scene-hez tartozik amit példányosítottak vagy "
+"Ez az erőforrás egy olyan jelenethez tartozik ami példányosított vagy "
"örökölt.\n"
-"A módosítások nem lesznek megtartva a jelenlegi Scene mentésekor."
+"A módosítások nem lesznek megtartva a jelenlegi jelenet mentésekor."
#: editor/editor_node.cpp
msgid ""
@@ -2410,21 +2318,19 @@ msgstr ""
"beállításait az import panelen, és importálja újból."
#: 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 ""
-"Ezt a jelenetet importálta, így a rajta végzett módosítások nem lesznek "
+"Ez a jelenetet importált, így a rajta végzett módosítások nem lesznek "
"megtartva.\n"
"Változtatásokat végezhet rajta, ha példányosítja, vagy leszármaztatja.\n"
"Olvassa el a jelenetek importálásáról szóló megfelelő dokumentációt, hogy "
"jobban megértse ezt a munkafolyamatot."
#: 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 "
@@ -2452,9 +2358,8 @@ msgid "Open Base Scene"
msgstr "Alap Scene megnyitás"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "Jelenet gyors megnyitása..."
+msgstr "Gyors megnyitás..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2473,9 +2378,8 @@ msgid "Save changes to '%s' before closing?"
msgstr "Bezárás előtt menti a '%s'-n végzett módosításokat?"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Saved %s modified resource(s)."
-msgstr "Nem sikerült betölteni az erőforrást."
+msgstr "%s módosított erőforrás mentve."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
@@ -2507,7 +2411,7 @@ msgstr "Mesh könyvtár exportálás"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr "Ezt a műveletet nem lehet végrehajtani gyökér Node nélkül."
+msgstr "Ezt a műveletet nem lehet végrehajtani gyökér node nélkül."
#: editor/editor_node.cpp
msgid "Export Tile Set"
@@ -2526,15 +2430,16 @@ msgid "Can't reload a scene that was never saved."
msgstr "Nem lehet újratölteni egy olyan jelenetet, amit soha nem mentett el."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reload Saved Scene"
-msgstr "Scene mentés"
+msgstr "Mentett jelenet újratöltése"
#: editor/editor_node.cpp
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"Az aktuális jelenet nem mentett módosításokat tartalmaz.\n"
+"A mentett jelenetet mindenképp újratölti? Ez a művelet nem visszavonható."
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2546,7 +2451,7 @@ msgstr "Kilépés"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr "Kilépés a szerkesztőből?"
+msgstr "Kilép a szerkesztőből?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
@@ -2554,11 +2459,12 @@ msgstr "Megnyitja a Projektkezelőt?"
#: editor/editor_node.cpp
msgid "Save & Quit"
-msgstr "Mentés és Kilépés"
+msgstr "Mentés és kilépés"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr "Elmenti a következő Scene(ek)en végzett változtatásokat kilépés előtt?"
+msgstr ""
+"Elmenti a következő jelenet(ek)en végzett változtatásokat kilépés előtt?"
#: editor/editor_node.cpp
msgid "Save changes the following scene(s) before opening Project Manager?"
@@ -2571,8 +2477,8 @@ msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
-"Ez a lehetőség elavult. Az olyan helyzeteket, ahol ki kell kényszeríteni egy "
-"frissítést, már hibának vesszük. Kérjük, jelentse a helyzetet."
+"Ez a lehetőség elavult. Az olyan helyzeteket, ahol kényszeríteni kell egy "
+"frissítést, már hibának vesszük. Kérjük, jelentse ezt."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
@@ -2580,12 +2486,11 @@ msgstr "Válasszon egy Fő Jelenetet"
#: editor/editor_node.cpp
msgid "Close Scene"
-msgstr "Scene bezárás"
+msgstr "Jelenet bezárása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "Scene bezárás"
+msgstr "Bezárt jelenet újbóli megnyitása"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2604,13 +2509,12 @@ msgid "Unable to load addon script from path: '%s'."
msgstr "Nem sikerült az addon szkript betöltése a következő útvonalról: '%s'."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
-"Nem sikerült az addon szkript betöltése a következő útvonalról: '%s' A "
-"szkript nem eszközmódban van."
+"Nem lehet betölteni az addon szkriptet a(z) '%s' útvonalról. Úgy tűnik, hiba "
+"történt a kódban, ellenőrizze a szintaxist."
#: editor/editor_node.cpp
msgid ""
@@ -2696,24 +2600,20 @@ msgstr "Alapértelmezett"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
-#, fuzzy
msgid "Show in FileSystem"
-msgstr "Mutassa a Fájlrendszerben"
+msgstr "Megjelenítés a fájlrendszerben"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Play This Scene"
-msgstr "Scene futtatás"
+msgstr "Jelenet lejátszása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "A Többi Lap Bezárása"
+msgstr "Lap bezárása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo Close Tab"
-msgstr "A Többi Lap Bezárása"
+msgstr "Lap bezárásának visszavonása"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
@@ -2721,12 +2621,11 @@ msgstr "A Többi Lap Bezárása"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Lapok bezárása ettől jobbra"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "Mind Bezárása"
+msgstr "Minden lap bezárása"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2769,9 +2668,8 @@ 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"
+msgstr "Szöveg másolása"
#: editor/editor_node.cpp
msgid "Next tab"
@@ -2779,7 +2677,7 @@ msgstr "Következő fül"
#: editor/editor_node.cpp
msgid "Previous tab"
-msgstr "Előző fül"
+msgstr "Előző lap"
#: editor/editor_node.cpp
msgid "Filter Files..."
@@ -2810,9 +2708,8 @@ msgid "Save Scene"
msgstr "Scene mentés"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
-msgstr "Minden Scene mentés"
+msgstr "Az összes jelenet mentése"
#: editor/editor_node.cpp
msgid "Convert To..."
@@ -2846,49 +2743,44 @@ msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Project Settings..."
-msgstr "Projekt Beállítások"
+msgstr "Projekt beállítások..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "Verzió:"
+msgstr "Verziókezelés"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Verziókezelés beállítása"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Verzióvezérlő leállítása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "Exportálás"
+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?"
+msgstr "Projektadat-mappa megnyitása"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
msgstr "Eszközök"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Orphan Resource Explorer..."
-msgstr "Árva Forrás Kezelő"
+msgstr "Árva erőforrás-kezelő..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr "Kilépés a Projektlistába"
+msgstr "Kilépés a projektlistába"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2901,24 +2793,28 @@ msgstr "Indítás Távoli Teszteléssel"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Exportáláskor vagy telepítéskor az így kapott futtatható program megpróbál "
-"ennek a számítógépnek az IP-jéhez csatlakozni távoli hibakeresés érdekében."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Kis Telepítés Hálózati FS-sel"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Ha ez az opció engedélyezve van, akkor az exportálás vagy a telepítés egy "
"minimális méretű futtatható programot hoz létre.\n"
@@ -2932,9 +2828,10 @@ msgid "Visible Collision Shapes"
msgstr "Látható Ütközési Alakzatok"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Az ütközési alakzatok és a fénysugárkövető Node-ok (mind 2D-hez és 3D-hez) "
"láthatóak lesznek a játék futásakor, ha ez az opció be van kapcsolva."
@@ -2944,23 +2841,26 @@ msgid "Visible Navigation"
msgstr "Látható Navigáció"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"A navigációs hálók és sokszögek láthatóak lesznek a játék futásakor, ha ez "
"az opció be van kapcsolva."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Jelenet változtatások szinkronizálása"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Ha ez a beállítás be van kapcsolva, bármilyen változtatás a jeleneten a "
"szerkesztőben le lesz másolva a futó játékba.\n"
@@ -2968,15 +2868,17 @@ msgstr ""
"fájlrendszerrel együtt."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Szkript Változtatások Szinkronizálása"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Ha ez a beállítás be van kapcsolva, bármilyen szkript, amit elment, újra "
"betöltődik a futó játékba.\n"
@@ -2988,56 +2890,49 @@ msgid "Editor"
msgstr "Szerkesztő"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Szerkesztő Beállítások"
+msgstr "Szerkesztő beállításai..."
#: editor/editor_node.cpp
msgid "Editor Layout"
msgstr "Szerkesztő Elrendezés"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Scene mentés"
+msgstr "Képernyőkép készítése"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "Szerkesztő Beállítások"
+msgstr "A képernyőképek a szerkesztő adatai/beállításai mappában tárolódnak."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
msgstr "Teljes Képernyő"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Toggle System Console"
-msgstr "Mód Váltása"
+msgstr "Rendszerkonzol be- és kikapcsolása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
-msgstr "Szerkesztő Beállítások"
+msgstr "Szerkesztő adatok/beállítások mappa megnyitása"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "A szerkesztő adatmappájának megnyitása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr "Szerkesztő Beállítások"
+msgstr "Szerkesztő beállításai mappa megnyitása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Editor Features..."
-msgstr "Export Sablonok Kezelése"
+msgstr "A Szerkesztő funkcióinak kezelése ..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "Export Sablonok Kezelése"
+msgstr "Exportálási sablonok kezelése..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
@@ -3048,7 +2943,7 @@ msgstr "Súgó"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Keresés"
@@ -3059,16 +2954,16 @@ msgstr "Online Dokumentáció"
#: editor/editor_node.cpp
msgid "Q&A"
-msgstr "Kérdések és Válaszok"
+msgstr "Kérdések és válaszok"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Újraimportálás"
+msgstr "Hiba bejelentése"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Visszajelzés a Dokumentumokról"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3088,11 +2983,11 @@ msgstr "Játék"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "Szüneteltesse a jelenet végrehajtását a hibakereséshez."
#: editor/editor_node.cpp
msgid "Pause Scene"
-msgstr "Scene szüneteltetés"
+msgstr "Jelenet szüneteltetése"
#: editor/editor_node.cpp
msgid "Stop the scene."
@@ -3112,37 +3007,33 @@ msgstr "Tetszőleges Scene futtatás"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr "Tetszőleges Scene futtatás"
+msgstr "Tetszőleges jelenet lejátszása"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
msgstr ""
+"A videó-illesztőprogram módosításához újra kell indítani a szerkesztőt."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Save & Restart"
-msgstr "Mentés és Kilépés"
+msgstr "Mentés és újraindítás"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Spins when the editor window redraws."
-msgstr "Fordul egyet, amikor a szerkesztőablak újrarajzolódik!"
+msgstr "Pörög, amikor a szerkesztőablak újrarajzolódik."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Folyamatos"
+msgstr "Folyamatos frissítés"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Változások Frissítése"
+msgstr "Frissítés, ha megváltozik"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Frissítési Forgó Kikapcsolása"
+msgstr "Frissítési forgó elrejtése"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -3153,9 +3044,8 @@ msgid "Inspector"
msgstr "Megfigyelő"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Expand Bottom Panel"
-msgstr "Összes kibontása"
+msgstr "Alsó panel kinyitása"
#: editor/editor_node.cpp
msgid "Output"
@@ -3170,9 +3060,8 @@ msgid "Android build template is missing, please install relevant templates."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "Export Sablonok Kezelése"
+msgstr "Sablonok kezelése"
#: editor/editor_node.cpp
msgid ""
@@ -3198,9 +3087,8 @@ msgid "Import Templates From ZIP File"
msgstr "Sablonok Importálása ZIP Fájlból"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Template Package"
-msgstr "Export Sablon Kezelő"
+msgstr "Sabloncsomag"
#: editor/editor_node.cpp
msgid "Export Library"
@@ -3228,7 +3116,7 @@ msgstr "Kiválaszt"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr "2D Szerkesztő Megnyitása"
+msgstr "2D szerkesztő megnyitása"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
@@ -3236,7 +3124,7 @@ msgstr "3D Szerkesztő Megnyitása"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Szkript Szerkesztő Megnyitása"
+msgstr "Szkript szerkesztő megnyitása"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3252,12 +3140,11 @@ msgstr "Előző Szerkesztő Megnyitása"
#: editor/editor_node.h
msgid "Warning!"
-msgstr ""
+msgstr "Figyelmeztetés!"
#: editor/editor_path.cpp
-#, fuzzy
msgid "No sub-resources found."
-msgstr "Nincs felületi forrás meghatározva."
+msgstr "Nem található alerőforrás."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
@@ -3268,14 +3155,12 @@ msgid "Thumbnail..."
msgstr "Indexkép..."
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "Szkript Futtatása"
+msgstr "Fő szkript:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit Plugin"
-msgstr "Sokszög Szerkesztése"
+msgstr "Bővítmény szerkesztése"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
@@ -3299,9 +3184,8 @@ msgid "Status:"
msgstr "Állapot:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit:"
-msgstr "Szerkesztés"
+msgstr "Szerkesztés:"
#: editor/editor_profiler.cpp
msgid "Measure:"
@@ -3344,34 +3228,32 @@ msgid "Calls"
msgstr "Hívások"
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "Tagok"
+msgstr "Szöveg szerkesztése:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "Be"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "Réteg"
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
-msgstr ""
+msgstr "%d bit, érték: %d"
#: editor/editor_properties.cpp
msgid "[Empty]"
-msgstr ""
+msgstr "[Üres]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
msgid "Assign..."
-msgstr ""
+msgstr "Hozzárendelés..."
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Invalid RID"
-msgstr "Érvénytelen név."
+msgstr ""
#: editor/editor_properties.cpp
msgid ""
@@ -3399,20 +3281,19 @@ msgstr ""
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
-msgstr ""
+msgstr "Új szkript"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Extend Script"
-msgstr "Szkript Futtatása"
+msgstr "Szkript kinyitása"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
-msgstr ""
+msgstr "Új %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Make Unique"
-msgstr ""
+msgstr "Egyedivé tétel"
#: editor/editor_properties.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
@@ -3430,7 +3311,7 @@ msgstr "Beillesztés"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
-msgstr ""
+msgstr "Átalakítás erre: %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
@@ -3438,35 +3319,35 @@ msgstr ""
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
-msgstr ""
+msgstr "Méret: "
#: editor/editor_properties_array_dict.cpp
msgid "Page: "
-msgstr ""
+msgstr "Oldal: "
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Item"
-msgstr ""
+msgstr "Elem eltávolítása"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "New Key:"
-msgstr "Új név:"
+msgstr "Új kulcs:"
#: editor/editor_properties_array_dict.cpp
-#, fuzzy
msgid "New Value:"
-msgstr "Új név:"
+msgstr "Új érték:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr ""
+msgstr "Kulcs/érték pár hozzáadása"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Nem található futtatható exportállomány ehhez a platformhoz.\n"
"Adjon hozzá egy futtatható exportállományt az export menüben."
@@ -3505,7 +3386,7 @@ msgstr "Válassza ki az importálandó Node-okat"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
-msgstr ""
+msgstr "Tallózás"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
@@ -3516,9 +3397,8 @@ msgid "Import From Node:"
msgstr "Importálás Node-ból:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Redownload"
-msgstr "Letöltés Megint"
+msgstr "Letöltés újra"
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -3558,9 +3438,8 @@ msgid "Can't open export templates zip."
msgstr "Nem nyitható meg az export sablon zip."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Invalid version.txt format inside templates: %s."
-msgstr "Érvénytelen version.txt formátum a sablonokban."
+msgstr "Érvénytelen version.txt formátum a sablonokban: %s."
#: editor/export_template_manager.cpp
msgid "No version.txt found inside templates."
@@ -3580,11 +3459,12 @@ msgstr "Importálás:"
#: editor/export_template_manager.cpp
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "Hiba történt a tükörlista lekérésekor."
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
msgstr ""
+"Hiba történt a tükörlista JSON elemzésénél. Kérjük, jelentse ezt a problémát!"
#: editor/export_template_manager.cpp
msgid ""
@@ -3611,7 +3491,7 @@ msgstr "Nincs válasz."
#: editor/export_template_manager.cpp
msgid "Request Failed."
-msgstr "Kérés Sikertelen."
+msgstr "A kérés sikertelen."
#: editor/export_template_manager.cpp
msgid "Redirect Loop."
@@ -3627,20 +3507,21 @@ 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ó:"
+msgstr "Az ideiglenes fájl nem távolítható el:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
"Templates installation failed.\n"
"The problematic templates archives can be found at '%s'."
msgstr ""
+"A sablonok telepítése nem sikerült.\n"
+"A problémás sablonok archívuma megtalálható a következő helyen: '%s'."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error requesting URL:"
-msgstr "Hiba történt az url lekérdezésekor: "
+msgstr "Hiba az URL kérésekor:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3689,9 +3570,8 @@ msgid "SSL Handshake Error"
msgstr "SSL-Kézfogás Hiba"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "Eszközök Kicsomagolása"
+msgstr ""
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3710,14 +3590,12 @@ msgid "Remove Template"
msgstr "Sablon Eltávolítása"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select Template File"
msgstr "Válasszon sablonfájlt"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Godot Export Templates"
-msgstr "Export Sablonok Kezelése"
+msgstr "Godot export sablonok"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
@@ -3728,14 +3606,13 @@ msgid "Download Templates"
msgstr "Sablonok Letöltése"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr "Válasszon tükröt a listából: "
+msgstr ""
+"Tükör kiválasztása a listából: (Shift + kattintás: megnyitás a böngészőben)"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Favorites"
-msgstr "Kedvencek:"
+msgstr "Kedvencek"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
@@ -3768,9 +3645,8 @@ msgid "No name provided."
msgstr "Nincs név megadva."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Provided name contains invalid characters."
-msgstr "A megadott név érvénytelen karaktereket tartalmaz"
+msgstr "A megadott név érvénytelen karaktereket tartalmaz."
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
@@ -3797,33 +3673,28 @@ msgid "Duplicating folder:"
msgstr "Mappa másolása:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
-msgstr "Új örökölt Jelenet..."
+msgstr "Új örökölt Jelenet"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Set As Main Scene"
-msgstr "Válasszon egy Fő Jelenetet"
+msgstr "Beállítás fő jelenetként"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open Scenes"
-msgstr "Scene megnyitás"
+msgstr "Jelenetek megnyitása"
#: editor/filesystem_dock.cpp
msgid "Instance"
msgstr "Példány"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
-msgstr "Kedvencek:"
+msgstr "Hozzáadás kedvencekhez"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Remove from Favorites"
-msgstr "Eltávolítás Csoportból"
+msgstr "Eltávolítás a kedvencek közül"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
@@ -3846,31 +3717,26 @@ msgid "Move To..."
msgstr "Áthelyezés..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Scene..."
-msgstr "Új Scene"
+msgstr "Új jelenet..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Script..."
-msgstr "Szkript gyors megnyitás..."
+msgstr "Új szkript..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Resource..."
-msgstr "Erőforrás Mentése Másként..."
+msgstr "Új erőforrás..."
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Expand All"
-msgstr "Összes kibontása"
+msgstr "Összes kinyitása"
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Collapse All"
-msgstr "Összes összecsukása"
+msgstr "Összes becsukása"
#: editor/filesystem_dock.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -3880,78 +3746,68 @@ msgid "Rename"
msgstr "Átnevezés"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Previous Folder/File"
-msgstr "Előző Sík"
+msgstr "Előző mappa/fájl"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Next Folder/File"
-msgstr "Mappa Létrehozása"
+msgstr "Következő mappa/fájl"
#: editor/filesystem_dock.cpp
msgid "Re-Scan Filesystem"
msgstr "Fájlrendszer Újra-vizsgálata"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Toggle Split Mode"
-msgstr "Mód Váltása"
+msgstr "Váltás az osztott módra"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Search files"
-msgstr "Osztályok Keresése"
+msgstr "Fájlok keresése"
#: editor/filesystem_dock.cpp
msgid ""
"Scanning Files,\n"
"Please Wait..."
msgstr ""
-"Fájlok Vizsgálata,\n"
-"Kérem Várjon..."
+"Fájlok vizsgálata,\n"
+"kérjük várjon..."
#: editor/filesystem_dock.cpp
msgid "Move"
msgstr "Áthelyezés"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "There is already file or folder with the same name in this location."
-msgstr "Egy fájl vagy mappa már létezik a megadott névvel."
+msgstr "Ezen a helyen már van azonos nevű fájl vagy mappa."
#: editor/filesystem_dock.cpp
msgid "Overwrite"
-msgstr ""
+msgstr "Felülírás"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Create Scene"
-msgstr "Scene mentés"
+msgstr "Jelenet létrehozása"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Szkript Létrehozása"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Find in Files"
-msgstr "%d további fájl"
+msgstr "Keresés a fájlokban"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find:"
-msgstr "Keres"
+msgstr "Keres:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Folder:"
-msgstr "Mappa Létrehozása"
+msgstr "Mappa:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Filters:"
-msgstr "Szűrők..."
+msgstr "Szűrők:"
#: editor/find_in_files.cpp
msgid ""
@@ -3973,29 +3829,24 @@ msgid "Cancel"
msgstr "Mégse"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find: "
-msgstr "Keres"
+msgstr "Keres: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace: "
-msgstr "Lecserélés"
+msgstr "Csere: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace all (no undo)"
-msgstr "Mind Lecserélése"
+msgstr "Összes lecserélése (nem visszavonható)"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Searching..."
-msgstr "Mentés..."
+msgstr "Keresés…"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Search complete"
-msgstr "Keresés a Szövegben"
+msgstr "A keresés kész"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4006,57 +3857,49 @@ 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!"
+msgstr "A csoportnév már létezik."
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Invalid group name."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen csoportnév."
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Rename Group"
-msgstr "Csoportok"
+msgstr "Csoport átnevezése"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Delete Group"
-msgstr "Elrendezés Törlése"
+msgstr "Csoport 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"
-msgstr "Hozzáadás Csoporthoz"
+msgstr "Csoportban nem lévő node-ok"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
#: editor/scene_tree_editor.cpp
msgid "Filter nodes"
-msgstr ""
+msgstr "Node-ok szűrése"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Nodes in Group"
-msgstr "Hozzáadás Csoporthoz"
+msgstr "Node-ok a csoportban"
#: editor/groups_editor.cpp
msgid "Empty groups will be automatically removed."
-msgstr ""
+msgstr "Az üres csoportok automatikusan törlődnek."
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group Editor"
-msgstr "Szkript Szerkesztő Megnyitása"
+msgstr "Csoportszerkesztő"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Manage Groups"
-msgstr "Csoportok"
+msgstr "Csoportok kezelése"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -4141,9 +3984,8 @@ msgid "Saving..."
msgstr "Mentés..."
#: editor/import_dock.cpp
-#, fuzzy
msgid "%d Files"
-msgstr " Fájlok"
+msgstr "%d fájl"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
@@ -4158,9 +4000,8 @@ msgid "Import As:"
msgstr "Importálás Mint:"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Preset"
-msgstr "Beépített Beállítások..."
+msgstr "Előre beállított"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4168,30 +4009,32 @@ msgstr "Újraimportálás"
#: editor/import_dock.cpp
msgid "Save Scenes, Re-Import, and Restart"
-msgstr ""
+msgstr "Jelenetek mentése, újraimportálás és újraindítás"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
msgstr ""
+"Az importált fájl típusának módosításához a szerkesztőt újra kell indítani."
#: editor/import_dock.cpp
+#, fuzzy
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
+"FIGYELMEZTETÉS: Vannak olyan eszközök, amelyek ezt az erőforrást használják, "
+"ezért leállíthatják a megfelelő betöltést."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
msgstr "Nem sikerült betölteni az erőforrást."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Expand All Properties"
-msgstr "Összes tulajdonság kibontása"
+msgstr "Összes tulajdonság kinyitása"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Collapse All Properties"
-msgstr "Összes tulajdonság összecsukása"
+msgstr "Összes tulajdonság becsukása"
#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -4203,9 +4046,8 @@ msgid "Copy Params"
msgstr "Paraméterek Másolása"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource Clipboard"
-msgstr "Az erőforrás vágólap üres!"
+msgstr "Erőforrás vágólap szerkesztése"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
@@ -4252,9 +4094,8 @@ msgid "Object properties."
msgstr "Objektumtulajdonságok."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Filter properties"
-msgstr "Objektumtulajdonságok."
+msgstr "Tulajdonságok szűrése"
#: editor/inspector_dock.cpp
msgid "Changes may be lost!"
@@ -4265,53 +4106,47 @@ msgid "MultiNode Set"
msgstr "MultiNode Beállítás"
#: editor/node_dock.cpp
-#, 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."
+msgstr "Válasszon ki egy node-ot a jelzések és csoportok módosításához."
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Edit a Plugin"
-msgstr "Sokszög Szerkesztése"
+msgstr "Bővítmény szerkesztése"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Create a Plugin"
-msgstr "Sokszög Létrehozása"
+msgstr "Bővítmény létrehozása"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Plugin Name:"
-msgstr "Bővítmények"
+msgstr "Bővítmény neve:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
-msgstr ""
+msgstr "Almappa:"
#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
msgid "Language:"
-msgstr ""
+msgstr "Nyelv:"
#: editor/plugin_config_dialog.cpp
msgid "Script Name:"
-msgstr ""
+msgstr "Szkript neve:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
-msgstr ""
+msgstr "Aktiválja most?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon"
-msgstr "Sokszög Létrehozása"
+msgstr "Sokszög létrehozása"
#: 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 "Pontok Törlése"
+msgstr "Pontok létrehozása."
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid ""
@@ -4325,28 +4160,24 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Erase points."
-msgstr "Jobb Egérgomb: Pont Törlése."
+msgstr "Pontok törlése."
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon"
-msgstr "Sokszög Szerkesztése"
+msgstr "Sokszög szerkesztése"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Insert Point"
msgstr "Pont Beszúrása"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon (Remove Point)"
-msgstr "Sokszög Szerkesztése (Pont Eltávolítása)"
+msgstr "Sokszög szerkesztése (pont eltávolítása)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Remove Polygon And Point"
-msgstr "Sokszög és Pont Eltávolítása"
+msgstr "Sokszög és pont eltávolítása"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4360,25 +4191,21 @@ msgstr "Animáció Hozzáadása"
#: 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 "Betöltés"
+msgstr "Betöltés..."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Move Node Point"
-msgstr "Pont Mozgatása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Limits"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Labels"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4388,20 +4215,17 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Node Point"
-msgstr "Pont hozzáadása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Animation Point"
-msgstr "Animáció Hozzáadása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace1D Point"
-msgstr "Útvonal Pont Eltávolítása"
+msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
@@ -4429,53 +4253,45 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
msgid "Enable snap and show grid."
-msgstr ""
+msgstr "Illesztés engedélyezése és rács megjelenítése."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Point"
-msgstr "Pont Mozgatása"
+msgstr "Pont"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Open Editor"
-msgstr "Megnyitás Szerkesztőben"
+msgstr "Szerkesztő megnyitása"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Open Animation Node"
-msgstr "Animáció Node"
+msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "HIBA: Animáció név már létezik!"
+msgstr "A háromszög már létezik."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Triangle"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr "Háromszög hozzáadása"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Limits"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Labels"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Point"
-msgstr "Útvonal Pont Eltávolítása"
+msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Remove BlendSpace2D Triangle"
@@ -4486,13 +4302,13 @@ msgid "BlendSpace2D does not belong to an AnimationTree node."
msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
+#, fuzzy
msgid "No triangles exist, so no blending can take place."
-msgstr ""
+msgstr "Nincsenek háromszögek, így nem történhet keverés."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Toggle Auto Triangles"
-msgstr "AutoLoad Globálisok Kapcsolása"
+msgstr "Automatikus háromszögek be- és kikapcsolása"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
@@ -4500,7 +4316,7 @@ msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
-msgstr ""
+msgstr "Pontok és háromszögek törlése."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
@@ -4512,9 +4328,8 @@ msgid "Blend:"
msgstr "Keverés:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Parameter Changed"
-msgstr "Változások Frissítése"
+msgstr "A paraméter megváltozott"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4531,9 +4346,8 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node Moved"
-msgstr "Mozgás Mód"
+msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
@@ -4541,41 +4355,35 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Connected"
-msgstr "Csatlakozva"
+msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Disconnected"
-msgstr "Kapcsolat bontva"
+msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "Animáció"
+msgstr "Animáció beállítása"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
-msgstr "Node létrehozás"
+msgstr "Node törlése"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "Node(-ok) törlése"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Filter On/Off"
-msgstr "Zavarmentes mód váltása."
+msgstr "Szűrő be- és kikapcsolása"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Change Filter"
-msgstr "Animáció hossz változtatás"
+msgstr "Szűrő módosítása"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4594,39 +4402,34 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Anim Clips"
-msgstr ""
+msgstr "Animáció klipek"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Animáció nyomvonal hozzáadás"
+msgstr "Audió klipek"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "Funkciók:"
+msgstr "Függvények"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "Node neve:"
+msgstr "Node átnevezve"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node..."
-msgstr ""
+msgstr "Node hozzáadása..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filtered Tracks:"
-msgstr "Szűrők Szerkesztése"
+msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
-msgstr "Animáció hossz változtatás"
+msgstr "Szűrés engedélyezése"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
@@ -4655,14 +4458,12 @@ msgid "Remove Animation"
msgstr "Animáció Eltávolítása"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Invalid animation name!"
-msgstr "HIBA: Érvénytelen animáció név!"
+msgstr "Érvénytelen animáció név!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Animation name already exists!"
-msgstr "HIBA: Animáció név már létezik!"
+msgstr "Az animáció név már létezik!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -4686,14 +4487,12 @@ msgid "Duplicate Animation"
msgstr "Animáció Megkettőzése"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "HIBA: Nincs másolható animáció!"
+msgstr "Nincs másolható animáció!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "HIBA: Nincs animációs erőforrás a vágólapon!"
+msgstr "Nincs animációs erőforrás a vágólapon!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
@@ -4704,9 +4503,8 @@ msgid "Paste Animation"
msgstr "Animáció Beillesztése"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "HIBA: Nincs animáció szerkesztésre!"
+msgstr "Nincs animáció szerkesztésre!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
@@ -4746,14 +4544,12 @@ msgid "Animation"
msgstr "Animáció"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "Átmenetek"
+msgstr "Átmenetek szerkesztése..."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Open in Inspector"
-msgstr "Megnyitás Szerkesztőben"
+msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
@@ -4768,9 +4564,8 @@ msgid "Enable Onion Skinning"
msgstr "Másolópapír Mód Bekapcsolása"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Onion Skinning Options"
-msgstr "Másolópapír Animáció (Onion Skinning)"
+msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
@@ -4813,9 +4608,8 @@ msgid "Include Gizmos (3D)"
msgstr "Kihatás Gizmókra Is (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Pin AnimationPlayer"
-msgstr "Animáció Beillesztése"
+msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
@@ -4845,24 +4639,21 @@ msgid "Cross-Animation Blend Times"
msgstr "Animációk Közötti Keverési Idők"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "Mozgás Mód"
+msgstr "Node áthelyezése"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Átmenet"
+msgstr "Az átmenet létezik!"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "Átmenet"
+msgstr "Átmenet hozzáadása"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "Node hozzáadása"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
@@ -4870,42 +4661,39 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
-msgstr ""
+msgstr "Azonnal"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "Szinkronizálás"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
-msgstr ""
+msgstr "A végén"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr ""
+msgstr "Utazás"
#: 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
-#, fuzzy
msgid "No playback resource set at path: %s."
-msgstr "Nincs az erőforrás elérési útban."
+msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Removed"
-msgstr "Eltávolít"
+msgstr "Node eltávolítva"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "Átmenet Node"
+msgstr "Átmenet eltávolítva"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
-msgstr ""
+msgstr "Start node beállítása (automatikus lejátszás)"
#: editor/plugins/animation_state_machine_editor.cpp
msgid ""
@@ -4915,19 +4703,16 @@ msgid ""
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Create new nodes."
-msgstr "Új %s Létrehozása"
+msgstr "Új node-ok létrehozása."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Connect nodes."
-msgstr "Csatlakoztatás Node-hoz:"
+msgstr "Node-ok csatlakoztatása."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Remove selected node or transition."
-msgstr "Kiválasztott nyomvonal eltávolítása."
+msgstr "Kiválasztott node vagy átmenet eltávolítása."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
@@ -4938,19 +4723,17 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition: "
-msgstr "Átmenet"
+msgstr "Átmenet: "
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Play Mode:"
-msgstr "Pásztázás Mód"
+msgstr "Lejátszási mód:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr "AnimációFa"
+msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -5117,37 +4900,32 @@ 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."
+msgstr "A kérés sikertelen."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Cannot save response to:"
-msgstr "Nem eltávolítható:"
+msgstr "A válasz nem menthető:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr ""
+msgstr "Írási hiba."
#: 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."
+msgstr "Hurok átirányítása."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed, timeout"
-msgstr "Kérés sikertelen, visszatérési kód:"
+msgstr "A kérés nem sikerült, időtúllépés"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Timeout."
-msgstr "Idő"
+msgstr "Időtúllépés."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
@@ -5172,14 +4950,12 @@ msgid "Asset Download Error:"
msgstr "Eszköz Letöltési Hiba:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading (%s / %s)..."
-msgstr "Letöltés"
+msgstr "Letöltés (%s / %s)..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading..."
-msgstr "Letöltés"
+msgstr "Letöltés..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Resolving..."
@@ -5194,9 +4970,8 @@ msgid "Idle"
msgstr "Tétlen"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Install..."
-msgstr "Telepítés"
+msgstr "Telepítés..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
@@ -5212,39 +4987,35 @@ msgstr "Ennek az eszköznek a letöltése már folyamatban van!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "Nemrég frissítve"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr ""
+msgstr "Legutóbb frissítve"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "Név (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "Név (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "Licenc"
+msgstr "Licenc (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "Licenc"
+msgstr "Licenc (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "First"
-msgstr "első"
+msgstr "Első"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Previous"
-msgstr "Előző fül"
+msgstr "Előző"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Next"
@@ -5252,7 +5023,7 @@ msgstr "Következő"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Last"
-msgstr ""
+msgstr "Utolsó"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "All"
@@ -5260,17 +5031,15 @@ msgstr "Mind"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr ""
+msgstr "Nincs találat a következőre: \"%s\"."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Import..."
-msgstr "Importálás"
+msgstr "Importálás..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Plugins..."
-msgstr "Bővítmények"
+msgstr "Bővítmények..."
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
msgid "Sort:"
@@ -5286,9 +5055,8 @@ msgid "Site:"
msgstr "Oldal:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Support"
-msgstr "Támogatás..."
+msgstr "Támogatás"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -5299,9 +5067,8 @@ msgid "Testing"
msgstr "Tesztelés"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Loading..."
-msgstr "Betöltés"
+msgstr "Betöltés..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -5338,7 +5105,7 @@ msgid "Bake Lightmaps"
msgstr "Fény Besütése"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Előnézet"
@@ -5356,12 +5123,11 @@ msgstr "Rács Léptetés:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "Elsődleges vonal minden:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "steps"
-msgstr "2 lépés"
+msgstr "lépés"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
@@ -5372,74 +5138,60 @@ msgid "Rotation Step:"
msgstr "Forgatási Léptetés:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale Step:"
-msgstr "Skála:"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Vertical Guide"
-msgstr "Függőleges vezetővonal mozgatása"
+msgstr "Függőleges segédvonal mozgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Vertical Guide"
-msgstr "Új függőleges vezetővonal létrehozása"
+msgstr "Függőleges segédvonal létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Vertical Guide"
-msgstr "Függőleges vezetővonal eltávolítása"
+msgstr "Függőleges segédvonal eltávolítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Horizontal Guide"
-msgstr "Vízszintes vezetővonal mozgatása"
+msgstr "Vízszintes segédvonal mozgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal Guide"
-msgstr "Új vízszintes vezetővonal létrehozása"
+msgstr "Vízszintes segédvonal létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Horizontal Guide"
-msgstr "Vízszintes vezetővonal eltávolítása"
+msgstr "Vízszintes segédvonal eltávolítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal and Vertical Guides"
-msgstr "Új vízszintes és függőleges vezetővonalak létrehozása"
+msgstr "Vízszintes és függőleges segédvonalak létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move pivot"
-msgstr "Forgatási Pont Mozgatása"
+msgstr "Forgatási pont áthelyezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem"
-msgstr "CanvasItem Szerkesztése"
+msgstr "CanvasItem forgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move anchor"
-msgstr "Mozgási Művelet"
+msgstr "Horgony áthelyezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Resize CanvasItem"
-msgstr "CanvasItem Szerkesztése"
+msgstr "CanvasItem átméretezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem"
-msgstr "CanvasItem Szerkesztése"
+msgstr "CanvasItem méretezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem"
-msgstr "CanvasItem Szerkesztése"
+msgstr "CanvasItem áthelyezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5458,62 +5210,52 @@ msgid ""
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Left"
-msgstr "Forgató mód"
+msgstr "Bal felső"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Right"
-msgstr "Sokszög Forgatása"
+msgstr "Jobb felső"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Right"
-msgstr "Sokszög Forgatása"
+msgstr "Jobb alsó"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Left"
-msgstr "Forgató mód"
+msgstr "Bal alsó"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Left"
-msgstr "Behúzás Balra"
+msgstr "Bal közép"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Top"
-msgstr "Kijelölés Középre"
+msgstr "Felső közép"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Right"
-msgstr "Behúzás Jobbra"
+msgstr "Jobbra közép"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Bottom"
-msgstr "Kijelölés Középre"
+msgstr "Középre lent"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
-msgstr ""
+msgstr "Középre"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Left Wide"
-msgstr "Bal lineáris"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Wide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Right Wide"
-msgstr "Jobb lineáris"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Wide"
@@ -5528,13 +5270,13 @@ msgid "HCenter Wide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Full Rect"
-msgstr ""
+msgstr "Teljes téglalap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Keep Ratio"
-msgstr "Méretezési arány:"
+msgstr "Arány megtartása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5564,45 +5306,39 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "Kiválaszt"
+msgstr "Kijelölés zárolása"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock Selected"
-msgstr ""
+msgstr "Kijelölés feloldása"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected"
-msgstr "Kiválasztás eltávolítás"
+msgstr "Kijelöltek csoportosítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Kiválasztás eltávolítás"
+msgstr "kijelölt csoportok szétbontása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
msgstr "Póz Beillesztése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Guides"
-msgstr "Póz Törlése"
+msgstr "Segédvonalak 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"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Bones"
-msgstr "Póz Törlése"
+msgstr "Csontok törlése"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
@@ -5621,9 +5357,8 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Zoom Reset"
-msgstr "Kicsinyítés"
+msgstr "Nagyítás visszaállítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5651,7 +5386,7 @@ 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"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5660,9 +5395,8 @@ 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"
+msgstr "Méretezési mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5682,32 +5416,26 @@ msgid "Pan Mode"
msgstr "Pásztázás Mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Ruler Mode"
-msgstr "Kiválasztó Mód"
+msgstr "Vonalzó mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle smart snapping."
-msgstr "Illesztés be- és kikapcsolása"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Smart Snap"
-msgstr "Illesztés Használata"
+msgstr "Intelligens illesztés használata"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle grid snapping."
-msgstr "Illesztés be- és kikapcsolása"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Grid Snap"
-msgstr "Illesztés Használata"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snapping Options"
msgstr "Illesztési beállítások"
@@ -5716,9 +5444,8 @@ msgid "Use Rotation Snap"
msgstr "Forgatási Illesztés Használata"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Scale Snap"
-msgstr "Illesztés Használata"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
@@ -5729,7 +5456,6 @@ msgid "Use Pixel Snap"
msgstr "Pixelhez Illesztés"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Smart Snapping"
msgstr "Intelligens illesztés"
@@ -5739,34 +5465,28 @@ 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"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Anchor"
-msgstr "Illesztés Node horgonyhoz"
+msgstr "Illesztés node horgonyhoz"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Sides"
-msgstr "Illesztés Node oldalakhoz"
+msgstr "Illesztés node oldalakhoz"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Center"
-msgstr "Illesztés Node horgonyhoz"
+msgstr "Illesztés node középponthoz"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
-msgstr "Illesztés más Node-okhoz"
+msgstr "Illesztés más node-okhoz"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
-msgstr "Illesztés vezetővonalakhoz"
+msgstr "Illesztés segédvonalakhoz"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5789,9 +5509,8 @@ msgid "Restores the object's children's ability to be selected."
msgstr "Újra kiválaszthatóvá teszi az objektum gyermekeit."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton Options"
-msgstr "Egyke"
+msgstr "Csontváz beállítások"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Bones"
@@ -5802,9 +5521,8 @@ msgid "Make Custom Bone(s) from Node(s)"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Custom Bones"
-msgstr "Csontok Törlése"
+msgstr "Egyéni csontok törlése"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5812,13 +5530,12 @@ msgid "View"
msgstr "Nézet"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Always Show Grid"
-msgstr "Rács Megjelenítése"
+msgstr "Rács megjelenítése mindig"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
-msgstr "Segítők Megjelenítése"
+msgstr "Segítők megjelenítése"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Rulers"
@@ -5842,7 +5559,7 @@ msgstr "Csoport Megjelenítése és ikonok zárolása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
-msgstr "Kijelölés Középre"
+msgstr "Kijelölés középre"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
@@ -5865,9 +5582,8 @@ msgid "Scale mask for inserting keys."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Insert keys (based on mask)."
-msgstr "Kulcs Beszúrása (Meglévő Nyomvonalakra)"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5878,14 +5594,12 @@ msgid ""
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Auto Insert Key"
-msgstr "Animáció kulcs beillesztés"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Animation Key and Pose Options"
-msgstr "Animáció hossza (másodpercben)"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
@@ -5897,7 +5611,7 @@ msgstr "Póz Másolása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
-msgstr "Póz Törlése"
+msgstr "Póz törlése"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
@@ -5908,9 +5622,8 @@ msgid "Divide grid step by 2"
msgstr "Rács Léptetés Mértékének Felezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Nézet"
+msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -5935,9 +5648,8 @@ msgid "Error instancing scene from %s"
msgstr "Hiba történt a Scene példányosításkor %s-ből"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Change Default Type"
-msgstr "Alapértelmezett típus megváltoztatása"
+msgstr "Alapértelmezett típus módosítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5948,9 +5660,8 @@ msgstr ""
"Fogd és vidd + Alt: Node típusának megváltoztatása"
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon3D"
-msgstr "Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly"
@@ -5973,9 +5684,8 @@ msgstr "Kibocsátási Maszk Betöltése"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "Újraindítás (mp):"
+msgstr "Újraindítás"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -6010,9 +5720,8 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Directed Border Pixels"
-msgstr "Könyvtárak és Fájlok:"
+msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -6022,12 +5731,12 @@ msgstr "Kinyerés Pixelből"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Colors"
-msgstr "Kibocsátási Színek"
+msgstr "Kibocsátási színek"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#, fuzzy
msgid "CPUParticles"
-msgstr "Részecskék"
+msgstr "CPU-részecskék"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -6045,7 +5754,6 @@ msgid "Flat 0"
msgstr "Lapos 0"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Flat 1"
msgstr "Lapos 1"
@@ -6074,22 +5782,18 @@ msgid "Load Curve Preset"
msgstr "Előre Beállított Görbe Betöltése"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
msgstr "Pont hozzáadása"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
msgstr "Pont eltávolítása"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Left Linear"
msgstr "Bal lineáris"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right Linear"
msgstr "Jobb lineáris"
@@ -6111,9 +5815,8 @@ msgid "Hold Shift to edit tangents individually"
msgstr "Tartsa lenyomva a Shift gombot az érintők egyenkénti szerkesztéséhez"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right click to add point"
-msgstr "Jobb Kattintás: Pont Törlése"
+msgstr "Kattintson a jobb gombbal a pont hozzáadásához"
#: editor/plugins/gi_probe_editor_plugin.cpp
msgid "Bake GI Probe"
@@ -6121,7 +5824,7 @@ msgstr "GI Szonda Besütése"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
-msgstr ""
+msgstr "Színátmenet szerkesztve"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -6144,9 +5847,8 @@ msgid "Mesh is empty!"
msgstr "A háló üres!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create a Trimesh collision shape."
-msgstr "Trimesh Ütközési Testvér Létrehozása"
+msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
@@ -6157,9 +5859,8 @@ msgid "This doesn't work on scene root!"
msgstr "Ez nem hajtható végre a gyökér Scene-en!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Trimesh Static Shape"
-msgstr "Trimesh Alakzat Létrehozása"
+msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create a single convex collision shape for the scene root."
@@ -6170,23 +5871,20 @@ msgid "Couldn't create a single convex collision shape."
msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Shape"
-msgstr "Konvex Alakzat Létrehozása"
+msgstr "Konvex alakzat létrehozása"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create multiple convex collision shapes for the scene root."
msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create any collision shapes."
-msgstr "Körvonalkészítés sikertelen!"
+msgstr "Nem sikerült ütközési alakzatokat létrehozni."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Shapes"
-msgstr "Konvex Alakzat Létrehozása"
+msgstr "Több konvex alakzat létrehozása"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
@@ -6255,9 +5953,8 @@ msgid ""
msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
-msgstr "Konvex Ütközési Testvér Létrehozása"
+msgstr "Konvex ütközési testvér létrehozása"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6266,9 +5963,8 @@ msgid ""
msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Collision Siblings"
-msgstr "Konvex Ütközési Testvér Létrehozása"
+msgstr "Több konvex ütközési testvér létrehozása"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6317,16 +6013,16 @@ msgid "Remove item %d?"
msgstr "%d elem eltávolítása?"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid ""
"Update from existing scene?:\n"
"%s"
-msgstr "Frissítés Jelenetből"
+msgstr ""
+"Frissíti a meglévő jelenetből?:\n"
+"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "Mesh Library"
-msgstr "MeshLibrary-ra..."
+msgstr "MeshLibrary"
#: editor/plugins/mesh_library_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -6447,12 +6143,11 @@ msgstr "Navigációs Sokszög Létrehozása"
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
msgid "Convert to CPUParticles"
-msgstr "Konvertálás Nagybetűsre"
+msgstr "Konvertálás CPU-részecskékké"
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Generating Visibility Rect"
-msgstr "Láthatósági Téglalap Generálása"
+msgstr "Láthatósági téglalap generálása"
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Generate Visibility Rect"
@@ -6472,23 +6167,20 @@ 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 "A Node nem tartalmaz geometriát (oldalakat)."
+msgstr "A geometria nem tartalmaz oldalakat."
#: editor/plugins/particles_editor_plugin.cpp
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."
+msgstr "A(z) \"%s\" nem tartalmaz geometriát."
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "\"%s\" doesn't contain face geometry."
-msgstr "A Node nem tartalmaz geometriát."
+msgstr "A(z) \"%s\" nem tartalmaz lapgeometriát."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6548,9 +6240,8 @@ msgid "Add Point to Curve"
msgstr "Pont Hozzáadása a Görbéhez"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Split Curve"
-msgstr "Görbe Lezárása"
+msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move Point in Curve"
@@ -6580,9 +6271,8 @@ msgid "Click: Add Point"
msgstr "Kattintás: Pont Hozzáadása"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Left Click: Split Segment (in curve)"
-msgstr "Szakasz Felosztása (görbén)"
+msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -6661,9 +6351,8 @@ msgid "Split Segment (in curve)"
msgstr "Szakasz Felosztása (görbén)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
-msgstr "Pont Mozgatása"
+msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
@@ -6671,9 +6360,8 @@ msgid ""
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Sync Bones"
-msgstr "Csontok Mutatása"
+msgstr "Csontok szinkronizálása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
@@ -6692,51 +6380,44 @@ msgid ""
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon & UV"
-msgstr "Sokszög Létrehozása"
+msgstr "Sokszög és UV létrehozása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Internal Vertex"
-msgstr "Új vízszintes vezetővonal létrehozása"
+msgstr "Belső csúcspont létrehozása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Internal Vertex"
-msgstr "Be-Vezérlő Pont Eltávolítása"
+msgstr "Belső csúcspont eltávolítása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Invalid Polygon (need 3 different vertices)"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Add Custom Polygon"
-msgstr "Sokszög Szerkesztése"
+msgstr "Egyéni sokszög hozzáadása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Custom Polygon"
-msgstr "Sokszög és Pont Eltávolítása"
+msgstr "Egyéni sokszög eltávolítása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Transform UV Map"
msgstr "UV Térkép Transzformálása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Transform Polygon"
-msgstr "Sokszög Létrehozása"
+msgstr "Sokszög átalakítása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint Bone Weights"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Open Polygon 2D UV editor."
-msgstr "2D UV Sokszög Szerkesztő"
+msgstr "2D UV sokszög szerkesztő megnyitása."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
@@ -6747,24 +6428,20 @@ msgid "UV"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Points"
-msgstr "Pont Mozgatása"
+msgstr "Pontok"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Polygons"
-msgstr "Sokszög -> UV"
+msgstr "Sokszögek"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Bones"
-msgstr "Csontok Létrehozása"
+msgstr "Csontok"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Points"
-msgstr "Pont Mozgatása"
+msgstr "Pontok mozgatása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
@@ -6825,9 +6502,8 @@ msgid "Clear UV"
msgstr "UV Törlése"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Settings"
-msgstr "Szerkesztő Beállítások"
+msgstr "Rács beállításai"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
@@ -6846,34 +6522,29 @@ msgid "Show Grid"
msgstr "Rács Megjelenítése"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Configure Grid:"
-msgstr "Illesztés Beállítása"
+msgstr "Rács beállítása:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset X:"
-msgstr "Rács Eltolás:"
+msgstr "Rács X eltolása:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset Y:"
-msgstr "Rács Eltolás:"
+msgstr "Rács Y eltolása:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step X:"
-msgstr "Rács Léptetés:"
+msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step Y:"
-msgstr "Rács Léptetés:"
+msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
msgid "Sync Bones to Polygon"
-msgstr "Sokszög Skálázása"
+msgstr "Csontok szinkronizálása a sokszöggel"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
@@ -6930,9 +6601,8 @@ msgid "AnimationTree has no path set to an AnimationPlayer"
msgstr ""
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Path to AnimationPlayer is invalid"
-msgstr "Az animációs fa érvénytelen."
+msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Files"
@@ -6943,54 +6613,44 @@ msgid "Close and save changes?"
msgstr "Bezárja és menti a változásokat?"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error writing TextFile:"
-msgstr "Hiba TileSet mentésekor!"
+msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Could not load file at:"
-msgstr "Nem sikerült létrehozni a mappát."
+msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "Hiba TileSet mentésekor!"
+msgstr "Hiba a fájl mentésekor!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "HIba történt a téma mentésekor"
+msgstr "Hiba történt a téma mentésekor."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
-msgstr "Hiba mentés közben"
+msgstr "Hiba a mentéskor"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "Hiba történt a téma importálásakor"
+msgstr "Hiba történt a téma importálásakor."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
msgstr "Hiba importáláskor"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Text File..."
-msgstr "Új Mappa..."
+msgstr "Új szövegfájl..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
-msgstr "Fálj Megnyitása"
+msgstr "Fájl megnyitása"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Save File As..."
-msgstr "Mentés Másként..."
+msgstr "Fájl mentése másként..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Can't obtain the script for running."
@@ -7026,9 +6686,8 @@ msgid "Save Theme As..."
msgstr "Téma Mentése Másként..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "%s Class Reference"
-msgstr " Osztály Referencia"
+msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -7041,18 +6700,16 @@ msgid "Find Previous"
msgstr "Előző Keresése"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Objektumtulajdonságok."
+msgstr "Szkriptek szűrése"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle alphabetical sorting of the method list."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter methods"
-msgstr "Objektumtulajdonságok."
+msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -7083,14 +6740,12 @@ msgid "File"
msgstr "Fájl"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "Megnyit"
+msgstr "Megnyitás..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Reopen Closed Script"
-msgstr "Szkript Futtatása"
+msgstr "Bezárt szkript újbóli megnyitása"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
@@ -7105,9 +6760,8 @@ msgid "Copy Script Path"
msgstr "Szkript Útvonal Másolása"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "History Previous"
-msgstr "Előző Előzmény"
+msgstr "Előző előzmény"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Next"
@@ -7119,9 +6773,8 @@ msgid "Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Import Theme..."
-msgstr "Téma Importálása"
+msgstr "Téma importálása..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Reload Theme"
@@ -7165,14 +6818,12 @@ msgid "Keep Debugger Open"
msgstr "Hibakereső Nyitva Tartása"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Debug with External Editor"
msgstr "Hibakeresés külső szerkesztővel"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open Godot online documentation."
-msgstr "Godot online dokumentáció megnyitása"
+msgstr "Godot online dokumentáció megnyitása."
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
@@ -7213,22 +6864,18 @@ msgid "Debugger"
msgstr "Hibakereső"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Search Results"
-msgstr "Keresés Súgóban"
+msgstr "Keresési eredmények"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Clear Recent Scripts"
-msgstr "Legutóbbi Jelenetek Törlése"
+msgstr "Legutóbbi szkriptek törlése"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Connections to method:"
-msgstr "Csatlakoztatás Node-hoz:"
+msgstr ""
#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source"
msgstr "Forrás"
@@ -7237,24 +6884,21 @@ msgid "Target"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
-msgstr "'%s' Lecsatlakoztatása '%s'-ról"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "[Ignore]"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Line"
-msgstr "Sor:"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function"
-msgstr "Ugrás Funkcióra..."
+msgstr "Ugrás függvényre"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
@@ -7266,9 +6910,8 @@ msgid "Can't drop nodes because script '%s' is not used in this scene."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Lookup Symbol"
-msgstr "Szimbólum Befejezése"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Pick Color"
@@ -7305,9 +6948,8 @@ msgid "Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Pontok Törlése"
+msgstr "Töréspontok"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -7356,66 +6998,56 @@ 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"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Sorvégi Szóközök Lenyírása"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Spaces"
-msgstr "Behúzások Átkonvertálása Szóközökre"
+msgstr "Behúzás átalakítása szóközökké"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Tabs"
-msgstr "Behúzások Átkonvertálása Tabokra"
+msgstr "Behúzás átalakítása tabokra"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
msgstr "Automatikus Behúzás"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Find in Files..."
-msgstr "Fájlok Szűrése..."
+msgstr "Keresés a fájlokban..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
msgstr "Kontextusérzékeny Súgó"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Toggle Bookmark"
-msgstr "Töréspont Elhelyezése"
+msgstr "Könyvjelző be- és kikapcsolása"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Next Bookmark"
-msgstr "Ugrás Következő Töréspontra"
+msgstr "Ugrás a következő könyvjelzőre"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Previous Bookmark"
-msgstr "Ugrás Előző Töréspontra"
+msgstr "Ugrás az előző könyvjelzőre"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Remove All Bookmarks"
-msgstr "Összes Töréspont Eltávolítása"
+msgstr "Összes könyvjelző eltávolítása"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function..."
-msgstr "Ugrás Funkcióra..."
+msgstr "Ugrás függvényre..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Line..."
-msgstr "Ugrás Sorra..."
+msgstr "Ugrás sorra..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -7427,23 +7059,18 @@ 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"
+msgstr "Ugrás a 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"
+msgstr "Ugrás az előző töréspontra"
#: editor/plugins/shader_editor_plugin.cpp
-#, fuzzy
msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
-"A alábbi fájlok újabbak a lemezen.\n"
-"Mit szeretne lépni?:"
#: editor/plugins/shader_editor_plugin.cpp
msgid "Shader"
@@ -7454,9 +7081,8 @@ msgid "This skeleton has no bones, create some children Bone2D nodes."
msgstr ""
#: editor/plugins/skeleton_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Rest Pose from Bones"
-msgstr "Kibocsátási Pontok Létrehozása A Mesh Alapján"
+msgstr ""
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Rest Pose to Bones"
@@ -7465,7 +7091,7 @@ msgstr ""
#: editor/plugins/skeleton_2d_editor_plugin.cpp
#, fuzzy
msgid "Skeleton2D"
-msgstr "Egyke"
+msgstr "Csontváz2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
@@ -7476,23 +7102,20 @@ msgid "Set Bones to Rest Pose"
msgstr ""
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Create physical bones"
-msgstr "Navigációs Háló Létrehozása"
+msgstr "Fizikai csontok létrehozása"
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton"
-msgstr "Egyke"
+msgstr "Csontváz"
#: editor/plugins/skeleton_editor_plugin.cpp
msgid "Create physical skeleton"
msgstr ""
#: editor/plugins/skeleton_ik_editor_plugin.cpp
-#, fuzzy
msgid "Play IK"
-msgstr "Játék"
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
@@ -7683,14 +7306,12 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Enable Doppler"
-msgstr "Animáció hossz változtatás"
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Cinematic Preview"
-msgstr "Háló Előnézetek Létrehozása"
+msgstr "Filmszerű előnézet"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Not available when using the GLES2 renderer."
@@ -7752,9 +7373,8 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Snap Nodes To Floor"
-msgstr "Rácshoz illesztés"
+msgstr "Node-ok illesztése a padlóhoz"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
@@ -7825,9 +7445,8 @@ msgid "Transform"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Snap Object to Floor"
-msgstr "Rácshoz illesztés"
+msgstr "Objektum illesztése a padlóhoz"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
@@ -7871,9 +7490,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Settings..."
-msgstr "Szerkesztő Beállítások"
+msgstr "Beállítások..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7940,48 +7558,40 @@ msgid "Nameless gizmo"
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Mesh2D"
-msgstr "Körvonalháló Készítése"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Mesh2D Preview"
-msgstr "Háló Előnézetek Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon2D"
-msgstr "Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Polygon2D Preview"
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create CollisionPolygon2D"
-msgstr "Navigációs Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "CollisionPolygon2D Preview"
-msgstr "Navigációs Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create LightOccluder2D"
-msgstr "Árnyékoló Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "LightOccluder2D Preview"
-msgstr "Árnyékoló Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Sprite is empty!"
-msgstr "A háló üres!"
+msgstr "A Sprite üres!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
@@ -7992,36 +7602,32 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Mesh2D"
-msgstr "Konvertálás Nagybetűsre"
+msgstr ""
#: 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 "Sokszög Mozgatása"
+msgstr ""
#: 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 "Navigációs Sokszög Létrehozása"
+msgstr ""
#: 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 "Árnyékoló Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
@@ -8040,19 +7646,16 @@ msgid "Grow (Pixels): "
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Update Preview"
-msgstr "Előnézet"
+msgstr "Előnézet frissítése"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "Szerkesztő Beállítások"
+msgstr "Beállítások:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "Kijelölés Keretezése"
+msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
@@ -8063,9 +7666,8 @@ msgid "Add Frame"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Unable to load images"
-msgstr "Nem sikerült betölteni az erőforrást."
+msgstr "Nem lehet betölteni a képeket"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
@@ -8092,22 +7694,19 @@ msgid "(empty)"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move Frame"
-msgstr "Mozgás Mód"
+msgstr "Keret mozgatása"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "Animáció"
+msgstr "Animációk:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "New Animation"
-msgstr "Animáció"
+msgstr "Új animáció"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8117,12 +7716,11 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
msgid "Animation Frames:"
-msgstr "Animáció Neve:"
+msgstr "Animációs képkockák:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add a Texture from File"
-msgstr "Kinyerés Pixelből"
+msgstr "Textúra hozzáadása fájlból"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
@@ -8145,9 +7743,8 @@ msgid "Move (After)"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "Kiválasztó Mód"
+msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
@@ -8158,9 +7755,8 @@ msgid "Vertical:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select/Clear All Frames"
-msgstr "Összes Kijelölése"
+msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Create Frames from Sprite Sheet"
@@ -8177,7 +7773,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
#, fuzzy
msgid "Set Margin"
-msgstr "Fogantyú Beállítása"
+msgstr "Margó beállítása"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
@@ -8233,9 +7829,8 @@ msgid "Remove All"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "Tagok"
+msgstr "Téma szerkesztése"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
@@ -8262,23 +7857,20 @@ msgid "Create From Current Editor Theme"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Button"
-msgstr "Automatikus Lejátszás Váltása"
+msgstr "Váltógomb"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Button"
-msgstr "Tiltva"
+msgstr "Letiltott gomb"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Item"
-msgstr "Tiltva"
+msgstr "Letiltott elem"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Check Item"
@@ -8307,12 +7899,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
msgid "Subitem 1"
-msgstr "%d elem"
+msgstr "Alelem 1"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
msgid "Subitem 2"
-msgstr "%d elem"
+msgstr "Alelem 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -8323,9 +7915,8 @@ msgid "Many"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled LineEdit"
-msgstr "Tiltva"
+msgstr "Letiltott szerkesztősor"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -8340,9 +7931,8 @@ msgid "Tab 3"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Editable Item"
-msgstr "Rádió Elem"
+msgstr "Szerkeszthető elem"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
@@ -8374,18 +7964,16 @@ msgid "Color"
msgstr "Szín"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Theme File"
-msgstr "Fálj Megnyitása"
+msgstr "Témafájl"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Fix Invalid Tiles"
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen csempék javítása"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -8413,9 +8001,8 @@ msgid "Erase TileMap"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "Következő Keresése"
+msgstr "Csempe keresése"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
@@ -8428,12 +8015,11 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Enable Priority"
-msgstr "Szűrők Szerkesztése"
+msgstr "Prioritás engedélyezése"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter tiles"
-msgstr "Fájlok Szűrése..."
+msgstr "Csempék szűrése"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
@@ -8454,14 +8040,12 @@ msgid "Pick Tile"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
-msgstr "Forgató mód"
+msgstr "Forgatás balra"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
-msgstr "Sokszög Forgatása"
+msgstr "Forgatás jobbra"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
@@ -8472,9 +8056,8 @@ msgid "Flip Vertically"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Transform"
-msgstr "Animáció transzformáció változtatás"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Add Texture(s) to TileSet."
@@ -8483,7 +8066,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "Jelenlegi tétel eltávolítása"
+msgstr "Távolítsa el a kijelölt textúrát a csempekészletből."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8498,27 +8081,24 @@ msgid "New Single Tile"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Autotile"
-msgstr "Fájlok Megtekintése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Atlas"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Next Coordinate"
-msgstr "Következő Szkript"
+msgstr "Következő koordináta"
#: 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 "Előző Szkript"
+msgstr "Előző koordináta"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the previous shape, subtile, or Tile."
@@ -8527,101 +8107,84 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
msgid "Region"
-msgstr "Forgató mód"
+msgstr "Régió"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision"
-msgstr "Animáció Node"
+msgstr "Ütközés"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion"
-msgstr "Sokszög Szerkesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation"
-msgstr "Navigációs Háló Létrehozása"
+msgstr "Navigáció"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
msgid "Bitmask"
-msgstr "Forgató mód"
+msgstr "Bitmaszk"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority"
-msgstr "Projekt Exportálása"
+msgstr "Prioritás"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index"
-msgstr "Pásztázás Mód"
+msgstr "Z index"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "Forgató mód"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "Animáció Node"
+msgstr "Ütközési mód"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion Mode"
-msgstr "Sokszög Szerkesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Mode"
-msgstr "Navigációs Háló Létrehozása"
+msgstr "Navigációs mód"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask Mode"
-msgstr "Forgató mód"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "Projekt Exportálása"
+msgstr "Prioritás mód"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "Pásztázás Mód"
+msgstr "Ikon mód"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index Mode"
-msgstr "Pásztázás Mód"
+msgstr "Z index mód"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste bitmask."
-msgstr "Animáció Beillesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Erase bitmask."
-msgstr "Jobb Egérgomb: Pont Törlése."
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new rectangle."
-msgstr "Új %s Létrehozása"
+msgstr "Új téglalap létrehozása."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "Új sokszög létrehozása a semmiből."
+msgstr "Új sokszög létrehozása."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
@@ -8641,9 +8204,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected texture? This will remove all tiles which use it."
-msgstr "Jelenlegi tétel eltávolítása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "You haven't selected a texture to remove."
@@ -8658,9 +8220,8 @@ msgid "Merge from scene?"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Texture"
-msgstr "Sablon Eltávolítása"
+msgstr "Textúra eltávolítása"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "%s file(s) were not added because was already on the list."
@@ -8673,9 +8234,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete selected Rect."
-msgstr "Törli a kiválasztott fájlokat?"
+msgstr "A kijelölt téglalap törlése."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8684,9 +8244,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "Pontok Törlése"
+msgstr "Sokszög törlése."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8720,111 +8279,92 @@ msgid "Set Tile Region"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Tile"
-msgstr "Mappa Létrehozása"
+msgstr "Csempe létrehozása"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Icon"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Bitmask"
-msgstr "Szűrők Szerkesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Collision Polygon"
-msgstr "Létező sokszög szerkesztése:"
+msgstr "Ütközési sokszög szerkesztése"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Occlusion Polygon"
-msgstr "Sokszög Szerkesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Navigation Polygon"
-msgstr "Navigációs Sokszög Létrehozása"
+msgstr "Navigációs sokszög szerkesztése"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste Tile Bitmask"
-msgstr "Animáció Beillesztése"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Clear Tile Bitmask"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Polygon Concave"
-msgstr "Sokszög Mozgatása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Polygon Convex"
-msgstr "Sokszög Mozgatása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Tile"
-msgstr "Sablon Eltávolítása"
+msgstr "Csempe eltávolítása"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Collision Polygon"
-msgstr "Sokszög és Pont Eltávolítása"
+msgstr "Ütközési sokszög eltávolítása"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Occlusion Polygon"
-msgstr "Árnyékoló Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Navigation Polygon"
-msgstr "Navigációs Sokszög Létrehozása"
+msgstr "Navigációs sokszög eltávolítása"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Priority"
-msgstr "Szűrők Szerkesztése"
+msgstr "Csempeprioritás szerkesztése"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Convex"
-msgstr "Sokszög Mozgatása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Concave"
-msgstr "Sokszög Mozgatása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Collision Polygon"
-msgstr "Navigációs Sokszög Létrehozása"
+msgstr "Ütközési sokszög létrehozása"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Occlusion Polygon"
-msgstr "Árnyékoló Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "This property can't be changed."
-msgstr "Ezt a műveletet nem lehet végrehajtani egy Scene nélkül."
+msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "TileSet-re..."
+msgstr "Csempekészlet"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No VCS addons are available."
@@ -8835,18 +8375,16 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "No commit message was provided"
-msgstr "Nincs név megadva"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit"
-msgstr "Közösség"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "VCS Addon is not initialized"
@@ -8859,59 +8397,51 @@ msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Initialize"
-msgstr "Szó Eleji Nagybetű"
+msgstr "Inicializálás"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Detect new changes"
-msgstr "Új %s Létrehozása"
+msgstr "Új változások észlelése"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Changes"
-msgstr "Változtatás"
+msgstr "Változások"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Renamed"
-msgstr "Átnevezés"
+msgstr "Átnevezve"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Deleted"
-msgstr "Törlés"
+msgstr "Törölve"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Typechange"
-msgstr "Változtatás"
+msgstr "Típusmódosítás"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Stage Selected"
-msgstr "Kiválasztás átméretezés"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Stage All"
-msgstr "Összes Mentése"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Add a commit message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit Changes"
-msgstr "Szkript Változtatások Szinkronizálása"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
@@ -8935,19 +8465,16 @@ msgid "(GLES3 only)"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Output"
-msgstr "Bemenet Hozzáadása"
+msgstr "Kimenet hozzáadása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "Skála:"
+msgstr "Skalár"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector"
-msgstr "Megfigyelő"
+msgstr "Vektor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
@@ -8958,81 +8485,70 @@ msgid "Sampler"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input port"
-msgstr "Bemenet Hozzáadása"
+msgstr "Bemeneti port hozzáadása"
#: 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 "Alapértelmezett típus megváltoztatása"
+msgstr "A bemeneti port típusának módosítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "Alapértelmezett típus megváltoztatása"
+msgstr "Kimeneti port típusának módosítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "Animáció Nevének Megváltoztatása:"
+msgstr "A bemeneti port nevének módosítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Change output port name"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove input port"
-msgstr "Pont eltávolítása"
+msgstr "Bemeneti port eltávolítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove output port"
-msgstr "Pont eltávolítása"
+msgstr "Kimeneti port eltávolítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Set expression"
-msgstr "Jelenlegi Verzió:"
+msgstr "Kifejezés beállítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Resize VisualShader node"
-msgstr "Árnyaló"
+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 "Beállítás Alapértelmezettként '%s'-hez"
+msgstr "Alapértelmezett bemeneti port beállítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Node to Visual Shader"
-msgstr "Árnyaló"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Duplicate Nodes"
-msgstr "Animáció kulcsok megkettőzése"
+msgstr "Node-ok duplikálása"
#: editor/plugins/visual_shader_editor_plugin.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Paste Nodes"
-msgstr ""
+msgstr "Node-ok beillesztése"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Nodes"
-msgstr "Node létrehozás"
+msgstr "Node-ok törlése"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Input Type Changed"
@@ -9051,28 +8567,25 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Show resulted shader code."
-msgstr "Node létrehozás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Create Shader Node"
-msgstr "Node létrehozás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Color function."
-msgstr "Ugrás Funkcióra..."
+msgstr "Szín függvény."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "Funkció Készítése"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
@@ -9083,9 +8596,8 @@ msgid "Converts RGB vector to HSV equivalent."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Funkció Készítése"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
@@ -9096,18 +8608,16 @@ msgid "Darken operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Csak A Különbségek"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "HardLight operator."
-msgstr "Skaláris kezelő változtatás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
@@ -9128,12 +8638,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Color constant."
-msgstr "Állandó"
+msgstr "Színállandó."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Animáció transzformáció változtatás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
@@ -9204,7 +8713,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
-msgstr "Vec állandó változtatás"
+msgstr "Logikai állandó."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
@@ -9217,7 +8726,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Input parameter."
-msgstr "Illesztés szülőhöz"
+msgstr "Bemeneti paraméter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
@@ -9246,12 +8755,12 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Scalar function."
-msgstr "Skalár-függvény változtatás"
+msgstr "Skalárfüggvény."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Scalar operator."
-msgstr "Skaláris kezelő változtatás"
+msgstr "Skalár operátor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
@@ -9478,12 +8987,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Scalar constant."
-msgstr "Skaláris állandó változtatás"
+msgstr "Skaláris állandó."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Egységes-skalár változtatás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
@@ -9506,9 +9014,8 @@ msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9550,24 +9057,22 @@ msgid "Multiplies vector by transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Sokszög Létrehozása"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Vector function."
-msgstr "Ugrás Funkcióra..."
+msgstr "Vektor függvény."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Vector operator."
-msgstr "Vec kezelő változtatás"
+msgstr "Vektor operátor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
@@ -9686,12 +9191,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Vector constant."
-msgstr "Vec állandó változtatás"
+msgstr "Vektor állandó."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "Egységes-vektor változtatás"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9759,19 +9263,16 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "VisualShader"
-msgstr "Árnyaló"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "Szűrők Szerkesztése"
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Visual Shader Mode Changed"
-msgstr "Árnyaló"
+msgstr ""
#: editor/project_export.cpp
msgid "Runnable"
@@ -9780,7 +9281,7 @@ msgstr ""
#: editor/project_export.cpp
#, fuzzy
msgid "Add initial export..."
-msgstr "Bemenet Hozzáadása"
+msgstr "Kezdeti exportálás hozzáadása..."
#: editor/project_export.cpp
msgid "Add previous patches..."
@@ -9812,9 +9313,8 @@ msgid "Release"
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "Exportálás"
+msgstr "Összes exportálása"
#: editor/project_export.cpp
msgid "The given export path doesn't exist:"
@@ -9841,7 +9341,7 @@ msgstr ""
#: editor/project_export.cpp
#, fuzzy
msgid "Export Path"
-msgstr "Projekt Exportálása"
+msgstr "Exportálási útvonal"
#: editor/project_export.cpp
msgid "Resources"
@@ -9888,9 +9388,8 @@ msgid "Make Patch"
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Pack File"
-msgstr " Fájlok"
+msgstr "Csomagfájl"
#: editor/project_export.cpp
msgid "Features"
@@ -9905,14 +9404,13 @@ msgid "Feature List:"
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Script"
-msgstr "Szkript Futtatása"
+msgstr "Szkript"
#: editor/project_export.cpp
#, fuzzy
msgid "Script Export Mode:"
-msgstr "Projekt Exportálása"
+msgstr "Szkript exportálás módja:"
#: editor/project_export.cpp
msgid "Text"
@@ -9943,19 +9441,16 @@ msgid "Export Project"
msgstr "Projekt Exportálása"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "Projekt Exportálása"
+msgstr "Exportálási mód?"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All"
-msgstr "Exportálás"
+msgstr "Összes exportálása"
#: editor/project_export.cpp editor/project_manager.cpp
-#, fuzzy
msgid "ZIP File"
-msgstr " Fájlok"
+msgstr "ZIP fájl"
#: editor/project_export.cpp
msgid "Godot Game Pack"
@@ -9974,14 +9469,13 @@ msgid "Export With Debug"
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path specified doesn't exist."
-msgstr "A fájl nem létezik."
+msgstr "A megadott útvonal nem létezik."
#: editor/project_manager.cpp
#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
-msgstr "Hiba a csomagfájl megnyitása során, nem zip formátumú."
+msgstr "Hiba a csomagfájl megnyitása során (az nem ZIP formátumú)."
#: editor/project_manager.cpp
msgid ""
@@ -10002,7 +9496,7 @@ msgstr ""
#: editor/project_manager.cpp
msgid "New Game Project"
-msgstr ""
+msgstr "Új játék projekt"
#: editor/project_manager.cpp
msgid "Imported Project"
@@ -10119,9 +9613,8 @@ msgid "Unnamed Project"
msgstr "Névtelen projekt"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Missing Project"
-msgstr "Meglévő Projekt Importálása"
+msgstr "Hiányzó projekt"
#: editor/project_manager.cpp
msgid "Error: Project is missing on the filesystem."
@@ -10130,11 +9623,12 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
msgid "Can't open project at '%s'."
-msgstr "'%s' nem nyitható meg."
+msgstr "A projekt nem nyitható meg a(z) %s helyen."
#: editor/project_manager.cpp
+#, fuzzy
msgid "Are you sure to open more than one project?"
-msgstr ""
+msgstr "Biztos, hogy egynél több projektet nyit meg?"
#: editor/project_manager.cpp
msgid ""
@@ -10168,15 +9662,11 @@ msgid ""
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Can't run project: no main scene defined.\n"
"Please edit the project and set the main scene in the Project Settings under "
"the \"Application\" category."
msgstr ""
-"Nincs meghatározva főjelenet, kiválaszt most egyet?\n"
-"Ezt megváltoztathatja később a \"Projekt Beállításokban\" az \"Alkalmazás\" "
-"kategóriában."
#: editor/project_manager.cpp
msgid ""
@@ -10218,14 +9708,14 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projektkezelő"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Projects"
-msgstr "Projekt"
+msgstr "Projektek"
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -10236,29 +9726,29 @@ msgid "Scan"
msgstr "Keresés"
#: editor/project_manager.cpp
+#, fuzzy
msgid "Select a Folder to Scan"
-msgstr ""
+msgstr "Válasszon egy beolvasandó mappát"
#: editor/project_manager.cpp
msgid "New Project"
-msgstr ""
+msgstr "Új projekt"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Pont eltávolítása"
+msgstr "Hiányzó eltávolítása"
#: editor/project_manager.cpp
msgid "Templates"
-msgstr ""
+msgstr "Sablonok"
#: editor/project_manager.cpp
msgid "Restart Now"
-msgstr ""
+msgstr "Újraindítás most"
#: editor/project_manager.cpp
msgid "Can't run project"
-msgstr ""
+msgstr "Nem lehet futtatni a projektet"
#: editor/project_manager.cpp
msgid ""
@@ -10275,7 +9765,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Key "
-msgstr ""
+msgstr "Kulcs "
#: editor/project_settings_editor.cpp
msgid "Joy Button"
@@ -10287,7 +9777,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Mouse Button"
-msgstr ""
+msgstr "Egérgomb"
#: editor/project_settings_editor.cpp
msgid ""
@@ -10296,18 +9786,16 @@ msgid ""
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "HIBA: Animáció név már létezik!"
+msgstr ""
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "Animáció Nevének Megváltoztatása:"
+msgstr ""
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
@@ -10315,7 +9803,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "All Devices"
-msgstr ""
+msgstr "Minden eszköz"
#: editor/project_settings_editor.cpp
msgid "Device"
@@ -10323,31 +9811,32 @@ msgstr "Eszköz"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr ""
+msgstr "Nyomj meg egy gombot..."
#: editor/project_settings_editor.cpp
+#, fuzzy
msgid "Mouse Button Index:"
-msgstr ""
+msgstr "Egérgomb index:"
#: editor/project_settings_editor.cpp
msgid "Left Button"
-msgstr ""
+msgstr "Bal gomb"
#: editor/project_settings_editor.cpp
msgid "Right Button"
-msgstr ""
+msgstr "Jobb gomb"
#: editor/project_settings_editor.cpp
msgid "Middle Button"
-msgstr ""
+msgstr "Középső gomb"
#: editor/project_settings_editor.cpp
msgid "Wheel Up Button"
-msgstr ""
+msgstr "Felfelé görgetés gomb"
#: editor/project_settings_editor.cpp
msgid "Wheel Down Button"
-msgstr ""
+msgstr "Lefelé görgetés gomb"
#: editor/project_settings_editor.cpp
msgid "Wheel Left Button"
@@ -10406,12 +9895,13 @@ msgid "Middle Button."
msgstr "Középső Egérgomb."
#: editor/project_settings_editor.cpp
+#, fuzzy
msgid "Wheel Up."
-msgstr ""
+msgstr "Felfelé görgetés."
#: editor/project_settings_editor.cpp
msgid "Wheel Down."
-msgstr ""
+msgstr "Lefelé görgetés."
#: editor/project_settings_editor.cpp
msgid "Add Global Property"
@@ -10445,16 +9935,15 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Error saving settings."
-msgstr ""
+msgstr "Hiba a beállítások mentésekor."
#: editor/project_settings_editor.cpp
msgid "Settings saved OK."
-msgstr ""
+msgstr "A beállítások sikeresen elmentve."
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Moved Input Action Event"
-msgstr "Pont Mozgatása a Görbén"
+msgstr ""
#: editor/project_settings_editor.cpp
msgid "Override for Feature"
@@ -10462,11 +9951,11 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Add Translation"
-msgstr ""
+msgstr "Fordítás hozzáadása"
#: editor/project_settings_editor.cpp
msgid "Remove Translation"
-msgstr ""
+msgstr "Fordítás eltávolítása"
#: editor/project_settings_editor.cpp
msgid "Add Remapped Path"
@@ -10521,9 +10010,8 @@ msgid "Action:"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Action"
-msgstr "Mozgási Művelet"
+msgstr "Művelet"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
@@ -10531,23 +10019,24 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Device:"
-msgstr ""
+msgstr "Eszköz:"
#: editor/project_settings_editor.cpp
msgid "Index:"
-msgstr ""
+msgstr "Index:"
#: editor/project_settings_editor.cpp
+#, fuzzy
msgid "Localization"
-msgstr ""
+msgstr "Lokalizáció"
#: editor/project_settings_editor.cpp
msgid "Translations"
-msgstr ""
+msgstr "Fordítások"
#: editor/project_settings_editor.cpp
msgid "Translations:"
-msgstr ""
+msgstr "Fordítások:"
#: editor/project_settings_editor.cpp
msgid "Remaps"
@@ -10570,14 +10059,12 @@ msgid "Locales Filter"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "Csontok Mutatása"
+msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "Csak Kiválsztás"
+msgstr ""
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
@@ -10613,11 +10100,11 @@ msgstr ""
#: editor/property_editor.cpp
msgid "File..."
-msgstr ""
+msgstr "Fájl..."
#: editor/property_editor.cpp
msgid "Dir..."
-msgstr ""
+msgstr "Könyvtár..."
#: editor/property_editor.cpp
msgid "Assign"
@@ -10652,55 +10139,53 @@ msgid "Select Method"
msgstr ""
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Batch Rename"
-msgstr "Átnevezés"
+msgstr "Csoportos átnevezés"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Csere: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "Jelenlegi Verzió:"
+msgstr "Reguláris kifejezés használata"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "Illesztési beállítások"
+msgstr "Haladó beállítások"
#: editor/rename_dialog.cpp
msgid "Substitute"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node name"
-msgstr "Node neve:"
+msgstr "Node neve"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "Node neve:"
+msgstr "Node típusa"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Current scene name"
-msgstr "Még nem mentette az aktuális jelenetet. Megnyitja mindenképp?"
+msgstr "Jelenlegi jelenet neve"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Root node name"
-msgstr "Átnevezés"
+msgstr ""
#: editor/rename_dialog.cpp
msgid ""
@@ -10713,7 +10198,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10721,9 +10206,8 @@ msgid "Initial value for the counter"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Step"
-msgstr "Lépés (mp):"
+msgstr "Lépés"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
@@ -10760,28 +10244,26 @@ msgid "Case"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Lowercase"
-msgstr "Mind Kisbetű"
+msgstr "Kisbetűssé"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Uppercase"
-msgstr "Mind Nagybetű"
+msgstr "Nagybetűssé"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Reset"
-msgstr "Nagyítás Visszaállítása"
+msgstr "Visszaállítás"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Reguláris kifejezés használata"
#: editor/rename_dialog.cpp
#, fuzzy
msgid "At character %s"
-msgstr "Érvényes karakterek:"
+msgstr "A(z) %s karakternél"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
@@ -10846,9 +10328,8 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach Script"
-msgstr "Szkript Létrehozása"
+msgstr "Szkript leválasztása"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
@@ -10879,19 +10360,16 @@ msgid "Instantiated scenes can't become root"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make node as Root"
-msgstr "Scene mentés"
+msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Node létrehozás"
+msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Node létrehozás"
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10902,9 +10380,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Node létrehozás"
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -10931,38 +10408,32 @@ msgid ""
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Local"
-msgstr "Csontok Létrehozása"
+msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "New Scene Root"
-msgstr "Scene mentés"
+msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "Node létrehozás"
+msgstr "Gyökér node létrehozása:"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "2D Scene"
-msgstr "Jelenet"
+msgstr "2D jelenet"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "3D Scene"
-msgstr "Jelenet"
+msgstr "3D jelenet"
#: editor/scene_tree_dock.cpp
msgid "User Interface"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "Node létrehozás"
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -11015,9 +10486,8 @@ msgid "Load As Placeholder"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
-msgstr "Godot online dokumentáció megnyitása"
+msgstr "Dokumentáció megnyitása"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11031,23 +10501,20 @@ msgid "Add Child Node"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Összes összecsukása"
+msgstr "Az összes kinyitása/becsukása"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Reparent to New Node"
-msgstr "Új %s Létrehozása"
+msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Scene Root"
-msgstr "Scene mentés"
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -11066,9 +10533,8 @@ msgid "Delete (No Confirm)"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Új %s Létrehozása"
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11081,9 +10547,8 @@ msgid "Attach a new or existing script to the selected node."
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach the script from the selected node."
-msgstr "Kiválasztott Scene(k) példányosítása a kiválasztott Node gyermekeként."
+msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Remote"
@@ -11098,24 +10563,22 @@ msgid "Clear Inheritance? (No Undo!)"
msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Toggle Visible"
-msgstr "Rejtett Fájlok Megjelenítése"
+msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "Egyszeri Node"
+msgstr "Node feloldása"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid "Button Group"
-msgstr "Hozzáadás Csoporthoz"
+msgstr "Gombcsoport"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid "(Connecting From)"
-msgstr "Kapcsolathiba"
+msgstr "(Csatlakozás innen)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
@@ -11140,9 +10603,8 @@ msgid ""
msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Szkript Futtatása"
+msgstr "Szkript megnyitása:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -11187,38 +10649,33 @@ msgid "Select a Node"
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "A háló üres!"
+msgstr "Az útvonal üres."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "A háló üres!"
+msgstr "A fájlnév üres."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is not local."
-msgstr "Az út nem vezeti a csomópontot!"
+msgstr "Az útvonal nem helyi."
#: editor/script_create_dialog.cpp
#, fuzzy
msgid "Invalid base path."
-msgstr "Érvénytelen Elérési Út."
+msgstr "Érvénytelen alapútvonal."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Egy fájl vagy mappa már létezik a megadott névvel."
+msgstr "Létezik ilyen nevű könyvtár."
#: editor/script_create_dialog.cpp
msgid "File does not exist."
msgstr "A fájl nem létezik."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Használjon érvényes kiterjesztést."
+msgstr "Érvénytelen kiterjesztés."
#: editor/script_create_dialog.cpp
msgid "Wrong extension chosen."
@@ -11245,61 +10702,52 @@ msgid "N/A"
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
-msgstr "Szkript Szerkesztő Megnyitása"
+msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script"
-msgstr "Szkript Futtatása"
+msgstr "Szkript megnyitása"
#: editor/script_create_dialog.cpp
msgid "File exists, it will be reused."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid path."
-msgstr "Érvénytelen Elérési Út."
+msgstr "Érvénytelen útvonal."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen osztálynév."
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "Az animációs fa érvényes."
+msgstr "A szkript útvonala/neve érvényes."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in script (into scene file)."
-msgstr "Műveletek Scene fájlokkal."
+msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Új %s Létrehozása"
+msgstr "Létrehoz egy új szkriptfájlt."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Meglévő Busz Elrendezés betöltése."
+msgstr "Egy meglévő szkriptfájlt tölt be."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script file already exists."
-msgstr "Már létezik '%s' AutoLoad!"
+msgstr "A szkriptfájl már létezik."
#: editor/script_create_dialog.cpp
msgid ""
@@ -11308,19 +10756,16 @@ msgid ""
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "Osztály:"
+msgstr "Osztálynév:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Template:"
-msgstr "Sablon Eltávolítása"
+msgstr "Sablon:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in Script:"
-msgstr "Szkript Futtatása"
+msgstr "Beépített szkript:"
#: editor/script_create_dialog.cpp
msgid "Attach Node Script"
@@ -11339,34 +10784,28 @@ msgid "Warning:"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Error:"
-msgstr "Hiba!"
+msgstr "Hiba:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error"
-msgstr "Hiba Másolása"
+msgstr "C++ hiba"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error:"
-msgstr "Hiba Másolása"
+msgstr "C++ hiba:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source"
-msgstr "Forrás"
+msgstr "C++ forrás"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source:"
-msgstr "Forrás"
+msgstr "Forrás:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source:"
-msgstr "Forrás"
+msgstr "C++ forrás:"
#: editor/script_editor_debugger.cpp
msgid "Stack Trace"
@@ -11377,9 +10816,8 @@ msgid "Errors"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Child process connected."
-msgstr "Kapcsolat bontva"
+msgstr "Gyermekfolyamat csatlakoztatva."
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
@@ -11390,9 +10828,8 @@ msgid "Video RAM"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Skip Breakpoints"
-msgstr "Pontok Törlése"
+msgstr "Töréspontok kihagyása"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -11411,9 +10848,8 @@ msgid "Profiler"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Network Profiler"
-msgstr "Projekt Exportálása"
+msgstr "Hálózati profilkészítő"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -11440,9 +10876,8 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Export list to a CSV file"
-msgstr "Projekt Exportálása"
+msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Resource Path"
@@ -11485,18 +10920,16 @@ msgid "Export measures as CSV"
msgstr ""
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Erase Shortcut"
-msgstr "Lassan Ki"
+msgstr ""
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Change Shortcut"
-msgstr "Horgonyok Módosítása"
+msgstr ""
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
@@ -11567,19 +11000,16 @@ msgid "Change Ray Shape Length"
msgstr ""
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Radius"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Height"
-msgstr "Keverési Idő Módosítása"
+msgstr ""
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Torus Inner Radius"
-msgstr "Horgonyok és Margók Módosítása"
+msgstr ""
#: modules/csg/csg_gizmos.cpp
msgid "Change Torus Outer Radius"
@@ -11626,9 +11056,8 @@ msgid "Enabled GDNative Singleton"
msgstr ""
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "Frissítési Forgó Kikapcsolása"
+msgstr ""
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -11707,14 +11136,12 @@ msgid "GridMap Delete Selection"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Fill Selection"
-msgstr "Minden kiválasztás"
+msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "Minden kiválasztás"
+msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -11781,18 +11208,16 @@ msgid "Cursor Clear Rotation"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Paste Selects"
-msgstr "Minden kiválasztás"
+msgstr "Kijelölés beillesztése"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clear Selection"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Fill Selection"
-msgstr "Minden kiválasztás"
+msgstr "Kijelölés kitöltése"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Settings"
@@ -11803,9 +11228,8 @@ msgid "Pick Distance:"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter meshes"
-msgstr "Objektumtulajdonságok."
+msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
@@ -11936,46 +11360,40 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "Bemenet Hozzáadása"
+msgstr "Bemeneti port hozzáadása"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "Bemenet Hozzáadása"
+msgstr "Kimeneti port hozzáadása"
#: 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."
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "Új %s Létrehozása"
+msgstr "Új függvény létrehozása."
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
-msgstr ""
+msgstr "Változók:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new variable."
-msgstr "Új %s Létrehozása"
+msgstr "Új változó létrehozása."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "Jelzések:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "Új sokszög létrehozása a semmiből."
+msgstr "Új jelzés létrehozása."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
-msgstr ""
+msgstr "A név nem érvényes azonosító:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
@@ -11983,46 +11401,43 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Function"
-msgstr ""
+msgstr "Függvény átnevezése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Variable"
-msgstr ""
+msgstr "Változó átnevezése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Signal"
-msgstr ""
+msgstr "Jelzés átnevezése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Function"
-msgstr ""
+msgstr "Függvény hozzáadása"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "Pont eltávolítása"
+msgstr "Bemeneti port törlése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
-msgstr ""
+msgstr "Változó hozzáadása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Signal"
-msgstr ""
+msgstr "Jelzés hozzáadása"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "Pont eltávolítása"
+msgstr "Bemeneti port eltávolítása"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "Pont eltávolítása"
+msgstr "Kimeneti port eltávolítása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
-msgstr ""
+msgstr "Kifejezés módosítása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
@@ -12095,19 +11510,16 @@ msgid "Connect Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Disconnect Nodes"
-msgstr "Kapcsolat bontva"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Data"
-msgstr "Csatlakoztatás Node-hoz:"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Sequence"
-msgstr "Csatlakoztatás Node-hoz:"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
@@ -12118,9 +11530,8 @@ msgid "Change Input Value"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "CanvasItem Szerkesztése"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
@@ -12151,58 +11562,52 @@ msgid "Try to only have one sequence input in selection."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "Körvonal Készítése"
+msgstr "Függvény létrehozása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
-msgstr ""
+msgstr "Függvény eltávolítása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Variable"
-msgstr ""
+msgstr "Változó eltávolítása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Variable:"
-msgstr ""
+msgstr "Változó szerkesztése:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Signal"
-msgstr ""
+msgstr "Jelzés eltávolítása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Signal:"
-msgstr ""
+msgstr "Jelzés szerkesztése:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Tool:"
-msgstr "Csontok Létrehozása"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
msgstr "Tagok:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "%s Típusának Megváltoztatása"
+msgstr "Alaptípus módosítása:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "%s Hozzáadása..."
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "Ugrás Funkcióra..."
+msgstr "Függvény hozzáadása..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "Funkciók:"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Select or create a function to edit its graph."
@@ -12210,7 +11615,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr ""
+msgstr "Kijelöltek törlése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
@@ -12222,34 +11627,31 @@ msgstr "Node-ok Másolása"
#: modules/visual_script/visual_script_editor.cpp
msgid "Cut Nodes"
-msgstr ""
+msgstr "Node-ok kivágása"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "Funkciók:"
+msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "Frissítés"
+msgstr "Grafikon frissítése"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
-msgstr "Tagok"
+msgstr "Tag szerkesztése"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
-msgstr ""
+msgstr "Beviteli típus nem iterálható: "
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid"
-msgstr ""
+msgstr "Az iterátor érvénytelenné vált"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid: "
-msgstr ""
+msgstr "Az iterátor érvénytelenné vált: "
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
@@ -12257,7 +11659,7 @@ msgstr ""
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Base object is not a Node!"
-msgstr ""
+msgstr "Az alap objektum nem egy node!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Path does not lead Node!"
@@ -12265,23 +11667,23 @@ msgstr "Az út nem vezeti a csomópontot!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name '%s' in node %s."
-msgstr ""
+msgstr "Érvénytelen index tulajdonság név: '%s' a(z) %s node-ban."
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
-msgstr ""
+msgstr ": Érvénytelen típusargumentum: "
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid arguments: "
-msgstr ""
+msgstr ": Érvénytelen argumentumok: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
-msgstr ""
+msgstr "VariableGet nem található a szkriptben: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableSet not found in script: "
-msgstr ""
+msgstr "VariableSet nem található a szkriptben: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
@@ -12294,9 +11696,8 @@ msgid ""
msgstr ""
#: modules/visual_script/visual_script_property_selector.cpp
-#, fuzzy
msgid "Search VisualScript"
-msgstr "Keresés Súgóban"
+msgstr ""
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
@@ -12369,9 +11770,8 @@ msgid "Invalid public key for APK expansion."
msgstr ""
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen csomagnév:"
#: platform/android/export/export.cpp
msgid ""
@@ -12440,9 +11840,8 @@ msgid "App Store Team ID not specified - cannot configure the project."
msgstr ""
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Invalid Identifier:"
-msgstr "Érvénytelen betűtípus méret."
+msgstr "Érvénytelen azonosító:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
@@ -12487,32 +11886,30 @@ msgstr ""
#: platform/uwp/export/export.cpp
#, fuzzy
msgid "Invalid package short name."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen rövid csomagnév."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package unique name."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen egyedi csomagnév."
#: platform/uwp/export/export.cpp
#, fuzzy
msgid "Invalid package publisher display name."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen csomagközzétevő megjelenítendő neve."
#: platform/uwp/export/export.cpp
#, fuzzy
msgid "Invalid product GUID."
-msgstr "Érvénytelen projektnév."
+msgstr "Érvénytelen termékazonosító."
#: platform/uwp/export/export.cpp
#, fuzzy
msgid "Invalid publisher GUID."
-msgstr "Érvénytelen Elérési Út."
+msgstr "Érvénytelen közzétevői GUID."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid background color."
-msgstr "Érvénytelen név."
+msgstr "Érvénytelen háttérszín."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
@@ -12803,6 +12200,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12903,43 +12305,36 @@ msgid "On BlendTree node '%s', animation not found: '%s'"
msgstr ""
#: scene/animation/animation_blend_tree.cpp
-#, fuzzy
msgid "Animation not found: '%s'"
-msgstr "Animációs Eszközök"
+msgstr "Az animáció nem található: '%s'"
#: scene/animation/animation_tree.cpp
msgid "In node '%s', invalid animation: '%s'."
msgstr ""
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Invalid animation: '%s'."
-msgstr "HIBA: Érvénytelen animáció név!"
+msgstr "Érvénytelen animáció: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "'%s' Lecsatlakoztatása '%s'-ról"
+msgstr ""
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
msgstr ""
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Path to an AnimationPlayer node containing animations is not set."
msgstr ""
-"Válasszon egy AnimationPlayer-t a Jelenetfából, hogy animációkat "
-"szerkeszthessen."
#: scene/animation/animation_tree.cpp
msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
msgstr ""
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "Az animációs fa érvénytelen."
+msgstr ""
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -12991,7 +12386,7 @@ msgstr "Figyelem!"
#: scene/gui/dialogs.cpp
msgid "Please Confirm..."
-msgstr "Kérem Erősítse Meg..."
+msgstr "Kérjük erősítse meg..."
#: scene/gui/popup.cpp
msgid ""
@@ -13040,17 +12435,15 @@ msgstr ""
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
-msgstr "Érvénytelen betűtípus méret."
+msgstr "Érvénytelen forrás az előnézethez."
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for shader."
-msgstr "Érvénytelen betűtípus méret."
+msgstr ""
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid comparison function for that type."
-msgstr "Érvénytelen betűtípus méret."
+msgstr ""
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
@@ -13068,6 +12461,14 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Exportáláskor vagy telepítéskor az így kapott futtatható program "
+#~ "megpróbál ennek a számítógépnek az IP-jéhez csatlakozni távoli "
+#~ "hibakeresés érdekében."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "A jelenlegi Scene soha nem volt még mentve, mentse el a futtatás előtt."
diff --git a/editor/translations/id.po b/editor/translations/id.po
index cf4bd738fa..7e94f233c1 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -20,7 +20,7 @@
# 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.
+# MonsterGila <fikrirazor@outlook.co.id>, 2019, 2020.
# Modeus Darksono <garuga17@gmail.com>, 2019.
# Akhmad Zulfikar <azuldegratz@gmail.com>, 2020.
# Ade Fikri Malihuddin <ade.fm97@gmail.com>, 2020.
@@ -31,8 +31,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-06 04:41+0000\n"
-"Last-Translator: yusuf afandi <afandi.yusuf.04@gmail.com>\n"
+"PO-Revision-Date: 2020-08-12 08:00+0000\n"
+"Last-Translator: MonsterGila <fikrirazor@outlook.co.id>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -551,6 +551,7 @@ msgid "Seconds"
msgstr "Detik"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -729,7 +730,7 @@ msgstr "Kasus Kecocokan"
msgid "Whole Words"
msgstr "Semua Kata"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Ganti"
@@ -921,6 +922,11 @@ msgid "Signals"
msgstr "Sinyal"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filter tile"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Anda yakin ingin menghapus semua hubungan dari sinyal ini?"
@@ -958,7 +964,7 @@ msgid "Recent:"
msgstr "Saat ini:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Cari:"
@@ -1139,6 +1145,9 @@ msgstr "Penemu Proyek"
msgid "Lead Developer"
msgstr "Pengembang Utama"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Manajer Proyek "
@@ -1160,6 +1169,16 @@ msgid "Gold Sponsors"
msgstr "Sponsor Emas"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Donatur Perak"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Donatur Perunggu"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Sponsor Mini"
@@ -1635,16 +1654,17 @@ msgid "Scene Tree Editing"
msgstr "Menyunting Pohon Skena"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Dok Impor"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Dok Node"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Dok Impor dan Berkas Sistem"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Berkas Sistem"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Dok Impor"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1908,7 +1928,7 @@ msgstr "Direktori-direktori & File-file:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Pratinjau:"
@@ -2435,10 +2455,13 @@ msgid "Reload Saved Scene"
msgstr "Simpan Skena"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"Skena saat ini mempunyai perubahan yang belum tersimpan.\n"
+"Tetap muat ulang skena yang tersimpan? Aksi ini tidak dapat dibatalkan."
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2785,24 +2808,28 @@ msgstr "Deploy dengan Awakutu Jarak Jauh"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Saat mengekspor atau mendeploy, hasil executable akan mencoba terhubung ke "
-"IP komputer untuk diawakutu."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Deploy Kecil dengan Jaringan FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Ketika opsi ini aktif, ekspor atau deploy akan menghasilkan minimal "
"executable.\n"
@@ -2815,9 +2842,10 @@ msgid "Visible Collision Shapes"
msgstr "Collision Shapes Terlihat"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Collision shapes dan raycast nodes (untuk 2D dan 3D) akan terlihat pada saat "
"permainan berjalan jika opsi ini aktif."
@@ -2827,23 +2855,26 @@ msgid "Visible Navigation"
msgstr "Navigasi Terlihat"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigasi meshes dan poligon akan terlihat saat game berjalan jika opsi ini "
"aktif."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sinkronkan Perubahan Skena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Ketika opsi ini aktif, perubahan yang dibuat pada skena melalui editor akan "
"direplika pada gim yang sedang berjalan.\n"
@@ -2851,15 +2882,17 @@ msgstr ""
"berkas sistem jaringan."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sinkronkan Perubahan Script"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Ketika opsi ini aktif, perubahan script yang tersimpan akan di muat kembali "
"pada permainan yang sedang berjalan.\n"
@@ -2923,7 +2956,7 @@ msgstr "Bantuan"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Cari"
@@ -3341,9 +3374,11 @@ msgid "Add Key/Value Pair"
msgstr "Tambahkan pasangan Key/Value"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Tidak ada preset ekspor yang bisa digunakan untuk platform ini.\n"
"Mohon tambahkan preset yang bisa digunakan di menu ekspor."
@@ -5103,7 +5138,7 @@ msgid "Bake Lightmaps"
msgstr "Panggang Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Pratinjau"
@@ -7750,7 +7785,8 @@ msgid "New Animation"
msgstr "Animasi Baru"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Kecepatan (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9884,6 +9920,7 @@ msgstr ""
"Apakah Anda yakin untuk memindai %s folder untuk proyek Godot yang ada?\n"
"Ini bisa memakan waktu yang lama."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Manajer Proyek"
@@ -10324,11 +10361,18 @@ msgid "Batch Rename"
msgstr "Ubah Nama Massal"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Ganti: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Awalan"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Akhiran"
#: editor/rename_dialog.cpp
@@ -10376,7 +10420,8 @@ msgid "Per-level Counter"
msgstr "Penghitung per Level"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Jika diatur, penghitung akan dimulai ulang untuk setiap grup node anak"
#: editor/rename_dialog.cpp
@@ -10436,7 +10481,8 @@ msgid "Reset"
msgstr "Reset"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Kesalahan Ekspresi Reguler"
#: editor/rename_dialog.cpp
@@ -10683,11 +10729,14 @@ msgid "Open Documentation"
msgstr "Buka Dokumentasi"
#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid ""
"Cannot attach a script: there are no languages registered.\n"
"This is probably because this editor was built with all language modules "
"disabled."
msgstr ""
+"Tidak dapat melampirkan skrip: tidak ada bahasa yang terdaftar.\n"
+"Ini mungkin karena editor ini dibuat dengan semua modul bahasa dinonaktifkan."
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
@@ -12240,10 +12289,14 @@ msgstr ""
"ciptakan resource shape untuknya!"
#: scene/2d/collision_shape_2d.cpp
+#, fuzzy
msgid ""
"Polygon-based shapes are not meant be used nor edited directly through the "
"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
msgstr ""
+"Bentuk Polygon-based tidak dimaksudkan untuk digunakan atau diedit secara "
+"langsung melalui node CollisionShape2D. Silakan gunakan node "
+"CollisionPolygon2D sebagai gantinya."
#: scene/2d/cpu_particles_2d.cpp
msgid ""
@@ -12429,8 +12482,9 @@ msgid "Finishing Plot"
msgstr "Menyelesaikan Pemetaan"
#: scene/3d/baked_lightmap.cpp
+#, fuzzy
msgid "Lighting Meshes: "
-msgstr ""
+msgstr "Lighting Meshes: "
#: scene/3d/collision_object.cpp
msgid ""
@@ -12485,8 +12539,9 @@ msgid ""
msgstr ""
#: scene/3d/cpu_particles.cpp
+#, fuzzy
msgid "Nothing is visible because no mesh has been assigned."
-msgstr ""
+msgstr "Tidak ada yang tampak karena tidak ada mesh yang ditetapkan."
#: scene/3d/cpu_particles.cpp
msgid ""
@@ -12506,6 +12561,11 @@ msgstr ""
"GIProbes tidak didukung oleh driver video GLES2.\n"
"Gunakan BakedLightmap sebagai gantinya."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12805,6 +12865,16 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex."
msgid "Constants cannot be modified."
msgstr "Konstanta tidak dapat dimodifikasi."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Dok Impor dan Berkas Sistem"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Saat mengekspor atau mendeploy, hasil executable akan mencoba terhubung "
+#~ "ke IP komputer untuk diawakutu."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Skena saat ini belum pernah disimpan, harap simpan terlebih dahulu "
diff --git a/editor/translations/is.po b/editor/translations/is.po
index d53a9d609d..b39913e3c6 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -536,6 +536,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -720,7 +721,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -910,6 +911,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -947,7 +952,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1122,6 +1127,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Verkefna Stjóri "
@@ -1143,6 +1151,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1607,15 +1623,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1880,7 +1896,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2709,22 +2725,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2733,8 +2753,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2743,32 +2763,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2829,7 +2849,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3231,7 +3251,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4972,7 +4993,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7576,7 +7597,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9587,6 +9608,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Verkefna Stjóri"
@@ -10021,11 +10043,15 @@ msgid "Batch Rename"
msgstr "Endurnefning Anim track"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10071,7 +10097,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10129,7 +10155,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12077,6 +12103,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index b2dac5ae0e..b16db7243d 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -54,12 +54,13 @@
# Lorenzo Asolan <brixiumx@gmail.com>, 2020.
# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020.
# Federico Manzella <ferdiu.manzella@gmail.com>, 2020.
+# Ziv D <wizdavid@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-05 16:58+0000\n"
-"Last-Translator: Lorenzo Cerqua <lorenzocerqua@tutanota.com>\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
+"Last-Translator: Mirko <miknsop@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -67,7 +68,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -578,6 +579,7 @@ msgid "Seconds"
msgstr "Secondi"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -730,7 +732,7 @@ msgstr "Cambia valore array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr "Va' alla linea"
+msgstr "Vai alla linea"
#: editor/code_editor.cpp
msgid "Line Number:"
@@ -756,7 +758,7 @@ msgstr "Distingui maiuscole"
msgid "Whole Words"
msgstr "Parole intere"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Sostituisci"
@@ -949,6 +951,11 @@ msgid "Signals"
msgstr "Segnali"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtra tiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Sei sicuro di voler rimuovere tutte le connessioni da questo segnale?"
@@ -986,7 +993,7 @@ msgid "Recent:"
msgstr "Recenti:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Cerca:"
@@ -1167,6 +1174,9 @@ msgstr "Fondatori del progetto"
msgid "Lead Developer"
msgstr "Sviluppatore principale"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Gestore progetto "
@@ -1188,6 +1198,14 @@ msgid "Gold Sponsors"
msgstr "Sponsor oro"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Sponsor Argento"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Sponsor Bronzo"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Sponsor mini"
@@ -1666,16 +1684,17 @@ msgid "Scene Tree Editing"
msgstr "Editor delle scene"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importa"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Nodo"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Filesystem e dock di importazione"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Filesystem"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importa"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1758,7 +1777,7 @@ msgstr "Nuovo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr "Importa"
+msgstr "Importare"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
@@ -1871,11 +1890,11 @@ msgstr "Torna indietro"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr "Va' avanti"
+msgstr "Vai avanti"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr "Va' su"
+msgstr "Vai su"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
@@ -1939,7 +1958,7 @@ msgstr "File e cartelle:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Anteprima:"
@@ -2741,7 +2760,7 @@ msgstr "Apri recente"
#: editor/editor_node.cpp
msgid "Save Scene"
-msgstr "Salva Scena"
+msgstr "Salva scena"
#: editor/editor_node.cpp
msgid "Save All Scenes"
@@ -2829,25 +2848,28 @@ msgstr "Distribuisci con Debug remoto"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"L'eseguibile, dopo l'esportazione o la distribuzione, attenterà di "
-"connettersi con l'indirizzo IP di questo computer per farsi eseguire il "
-"debug."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Piccola distribuzione con la rete FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Quando questa opzione è abilitata, l'esportazione o distribuzione produrrà "
"un eseguibile minimale.\n"
@@ -2861,9 +2883,10 @@ msgid "Visible Collision Shapes"
msgstr "Forme di collisione visibili"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Le forme di collisione e i nodi di raycast (per il 2D e 3D) saranno visibili "
"nel gioco in esecuzione se l'opzione è attiva."
@@ -2873,23 +2896,26 @@ msgid "Visible Navigation"
msgstr "Navigazione Visibile"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Le mesh e i poligoni di navigazione saranno visibili nel gioco in esecuzione "
"se l'opzione è attiva."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizza cambiamenti scena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Quando questa opzione è attiva, qualsiasi cambiamento fatto alla scena "
"nell'editor sarà replicato nel gioco in esecuzione.\n"
@@ -2897,15 +2923,17 @@ msgstr ""
"filesystem in rete."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizza cambiamenti script"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Quando questa opzione è attiva, qualsiasi script salvato verrà ricaricato "
"nel gioco in esecuzione.\n"
@@ -2970,7 +2998,7 @@ msgstr "Aiuto"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Cerca"
@@ -3025,7 +3053,7 @@ msgstr "Esegui la scena in modifica."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Avvia Scena"
+msgstr "Esegui scena"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -3033,7 +3061,7 @@ msgstr "Esegui scena personalizzata"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr "Avvia Scena Personalizzata"
+msgstr "Avvia scena personalizzata"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
@@ -3159,11 +3187,11 @@ msgstr "Apri Editor 2D"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr "Apri editor 3D"
+msgstr "Apri Editor 3D"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Apri editor degli script"
+msgstr "Apri Editor degli script"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3390,9 +3418,11 @@ msgid "Add Key/Value Pair"
msgstr "Aggiungi Coppia Chiave/Valore"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Non sono stati trovati dei modelli di export eseguibili per questa "
"piattaforma.\n"
@@ -4800,7 +4830,7 @@ msgstr "Modalità Gioco:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr "AnimazioneAlbero"
+msgstr "AnimationTree"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -5169,7 +5199,7 @@ msgid "Bake Lightmaps"
msgstr "Preprocessa Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Anteprima"
@@ -5604,7 +5634,7 @@ msgstr "Vista"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
-msgstr "Mostra Sempre Griglia"
+msgstr "Mostra sempre Griglia"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
@@ -7006,7 +7036,7 @@ msgstr "Linea"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function"
-msgstr "Va' alla funzione"
+msgstr "Vai alla funzione"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
@@ -7830,7 +7860,8 @@ msgid "New Animation"
msgstr "Nuova Animazione"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocità (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8259,7 +8290,7 @@ msgstr "Modalità Regione"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision Mode"
-msgstr "Modalità di collisione"
+msgstr "Modalità Collisioni"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Occlusion Mode"
@@ -8275,7 +8306,7 @@ msgstr "Modalità Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Priority Mode"
-msgstr "Modalità Prioritaria"
+msgstr "Modalità Priorità"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon Mode"
@@ -9970,6 +10001,7 @@ msgstr ""
"esistenti?\n"
"Per questo potrebbe volerci un pò."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestore dei progetti"
@@ -10410,11 +10442,18 @@ msgid "Batch Rename"
msgstr "Rinomina in blocco"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Sostituisci: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefisso"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Suffisso"
#: editor/rename_dialog.cpp
@@ -10462,7 +10501,8 @@ msgid "Per-level Counter"
msgstr "Contatore per Livello"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Se impostato, il contatore si riavvia per ogni gruppo di nodi figlio"
#: editor/rename_dialog.cpp
@@ -10522,7 +10562,8 @@ msgid "Reset"
msgstr "Reset"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Errore Espressione Regolare"
#: editor/rename_dialog.cpp
@@ -11913,7 +11954,7 @@ msgstr "Seleziona o crea una funzione per modificarne il grafico."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr "Elimina Selezionati"
+msgstr "Elimina selezionati"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
@@ -12058,7 +12099,7 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
-"Debug keystore non configurato correttamente nel preset di esportazione."
+"Release keystore non configurato correttamente nel preset di esportazione."
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
@@ -12191,9 +12232,8 @@ msgid "Run in Browser"
msgstr "Esegui nel Browser"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Run exported HTML in the system's default browser."
-msgstr "Esegui HTML esportato all'interno del browser di sistema predefinito."
+msgstr "Esegui il codice HTML esportato nel browser di sistema predefinito."
#: platform/javascript/export/export.cpp
msgid "Could not write file:"
@@ -12216,9 +12256,8 @@ msgid "Could not read boot splash image file:"
msgstr "Impossibile leggere il file immagine di avvio splash:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Using default boot splash image."
-msgstr "Utilizzando l'immagine di splash di avvio predefinita."
+msgstr "Utilizzando l'immagine splash predefinita."
#: platform/uwp/export/export.cpp
msgid "Invalid package short name."
@@ -12628,6 +12667,11 @@ msgstr ""
"Le GIProbes non sono supportate dal driver video GLES2.\n"
"In alternativa, usa una BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12934,6 +12978,17 @@ msgstr "Varyings può essere assegnato soltanto nella funzione del vertice."
msgid "Constants cannot be modified."
msgstr "Le constanti non possono essere modificate."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Filesystem e dock di importazione"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "L'eseguibile, dopo l'esportazione o la distribuzione, attenterà di "
+#~ "connettersi con l'indirizzo IP di questo computer per farsi eseguire il "
+#~ "debug."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "La scena attuale non è mai stata salvata, si prega di salvarla prima di "
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index e0a1d4d909..d1a368346d 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -36,7 +36,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
@@ -45,7 +45,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -557,6 +557,7 @@ msgid "Seconds"
msgstr "秒"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "フレームレート(FPS)"
@@ -608,7 +609,7 @@ msgstr "前のステップへ"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr "アニメーションの最適化"
+msgstr "アニメーションを最適化"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
@@ -735,7 +736,7 @@ msgstr "大文字小文字を区別する"
msgid "Whole Words"
msgstr "単語全体"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "置換"
@@ -926,6 +927,11 @@ msgid "Signals"
msgstr "シグナル"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "タイルを絞り込む"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "このシグナルからすべての接続を除去してもよろしいですか?"
@@ -963,7 +969,7 @@ msgid "Recent:"
msgstr "最近:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "検索:"
@@ -1143,6 +1149,9 @@ msgstr "プロジェクト創始者"
msgid "Lead Developer"
msgstr "開発リーダー"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "プロジェクトマネージャー "
@@ -1164,6 +1173,14 @@ msgid "Gold Sponsors"
msgstr "ゴールドスポンサー"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "シルバースポンサー"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "ブロンズスポンサー"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "ミニスポンサー"
@@ -1640,16 +1657,17 @@ 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 "ファイルシステムとインポートドック"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "ファイルシステム"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "インポートドック"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1914,7 +1932,7 @@ msgstr "ディレクトリとファイル:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "プレビュー:"
@@ -2751,11 +2769,11 @@ msgstr "バージョンコントロール"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr "バージョン管理のセットアップ"
+msgstr "バージョン管理をセットアップ"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr "バージョン管理の終了"
+msgstr "バージョン管理を終了"
#: editor/editor_node.cpp
msgid "Export..."
@@ -2792,24 +2810,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"エクスポートまたはデプロイを行う場合、生成された実行ファイルはデバッグのため"
-"に、このコンピューターのIPに接続を試みます。"
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "ネットワークファイルシステムでスモールデプロイ"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"このオプションを有効にすると、エクスポートまたはデプロイ時に最小限の実行可能"
"ファイルが生成されます。\n"
@@ -2823,9 +2845,10 @@ msgid "Visible Collision Shapes"
msgstr "コリジョン形状の表示"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"このオプションを有効にすると、コリジョン形状とレイキャストノードが、ゲーム実"
"行中にも表示されるようになります。"
@@ -2835,38 +2858,43 @@ msgid "Visible Navigation"
msgstr "ナビゲーションの表示"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"このオプションを有効にすると、ナビゲーションメッシュが、ゲーム実行中にも表示"
"されるようになります。"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "シーンの変更を同期"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"このオプションを有効にすると、エディタからシーンに加えられた変更が、実行中の"
"ゲームに反映されるようになります。\n"
"リモート実行の場合、ネットワークファイルシステムを使うとより効果的です。"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "スクリプトの変更を同期"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"このオプションを有効にすると、保存したスクリプトが、実行中のゲームに反映され"
"るようになります。\n"
@@ -2894,11 +2922,11 @@ msgstr "スクリーンショットはEditor Data / Settingsフォルダに保
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "フルスクリーンの有効化 / 無効化"
+msgstr "フルスクリーンを有効化 / 無効化"
#: editor/editor_node.cpp
msgid "Toggle System Console"
-msgstr "システムコンソールの有効化 / 無効化"
+msgstr "システムコンソールを有効化 / 無効化"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2929,7 +2957,7 @@ msgstr "ヘルプ"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "検索"
@@ -3347,9 +3375,11 @@ msgid "Add Key/Value Pair"
msgstr "キー/値のペアを追加"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"このプラットフォームで実行可能なエクスポートプリセットがありません。\n"
"エクスポートメニューに実行可能なプリセットを追加してください。"
@@ -5109,7 +5139,7 @@ msgid "Bake Lightmaps"
msgstr "ライトマップを焼き込む"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "プレビュー"
@@ -7011,11 +7041,11 @@ msgstr "右インデント"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Comment"
-msgstr "コメントの切り替え"
+msgstr "コメントアウト / 解除"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
-msgstr "行を折りたたむ / 展開する"
+msgstr "行を折りたたむ / 展開"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
@@ -7023,7 +7053,7 @@ msgstr "すべての行を折りたたむ"
#: editor/plugins/script_text_editor.cpp
msgid "Unfold All Lines"
-msgstr "すべての行を展開する"
+msgstr "すべての行を展開"
#: editor/plugins/script_text_editor.cpp
msgid "Clone Down"
@@ -7035,7 +7065,7 @@ msgstr "シンボルを補完"
#: editor/plugins/script_text_editor.cpp
msgid "Evaluate Selection"
-msgstr "選択範囲を評価する"
+msgstr "選択範囲を評価"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
@@ -7753,7 +7783,8 @@ msgid "New Animation"
msgstr "新規アニメーション"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "速度(FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9873,6 +9904,7 @@ msgstr ""
"既存のGodotプロジェクトの%sフォルダをスキャンしますか?\n"
"これにはしばらく時間がかかります。"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "プロジェクトマネージャー"
@@ -10313,11 +10345,18 @@ msgid "Batch Rename"
msgstr "名前の一括変更"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "置換: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "プレフィックス"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "サフィックス"
#: editor/rename_dialog.cpp
@@ -10365,7 +10404,8 @@ msgid "Per-level Counter"
msgstr "レベルごとのカウンター"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "設定すると、子ノードのグループごとにカウンタが再起動します"
#: editor/rename_dialog.cpp
@@ -10425,7 +10465,8 @@ msgid "Reset"
msgstr "リセット"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "正規表現エラー"
#: editor/rename_dialog.cpp
@@ -12504,6 +12545,11 @@ msgstr ""
"GIProbesはGLES2ビデオドライバではサポートされていません。\n"
"代わりにBakedLightmapを使用してください。"
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "90度を超える角度のスポットライトは、シャドウを投影できません。"
@@ -12808,6 +12854,16 @@ msgstr "Varying変数は頂点関数にのみ割り当てることができま
msgid "Constants cannot be modified."
msgstr "定数は変更できません。"
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "ファイルシステムとインポートドック"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "エクスポートまたはデプロイを行う場合、生成された実行ファイルはデバッグのた"
+#~ "めに、このコンピューターのIPに接続を試みます。"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "現在のシーンは保存されませんでした。実行する前に保存してください。"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 1bfd23080b..a59a42333f 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -552,6 +552,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -738,7 +739,7 @@ msgstr "საქმის დამთხვევა"
msgid "Whole Words"
msgstr "მთლიანი სიტყვები"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "ჩანაცვლება"
@@ -941,6 +942,11 @@ msgid "Signals"
msgstr "სიგნალები"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "დამაკავშირებელი სიგნალი:"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -979,7 +985,7 @@ msgid "Recent:"
msgstr "ბოლო:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "ძებნა:"
@@ -1164,6 +1170,9 @@ msgstr "პროექტის დამფუძნებლები"
msgid "Lead Developer"
msgstr "მთავარი დეველოპერი"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "პროექტის მენეჯერი. "
@@ -1185,6 +1194,16 @@ msgid "Gold Sponsors"
msgstr "ოქროს სპონსორები"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "ვერცხლის დონატორები"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "ბრინჯაოს დონატორები"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "მინი სპონსორები"
@@ -1661,15 +1680,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1944,7 +1963,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2789,22 +2808,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2813,8 +2836,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2823,32 +2846,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2909,7 +2932,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3313,7 +3336,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5092,7 +5116,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7742,7 +7766,7 @@ msgid "New Animation"
msgstr "ანიმაციის ოპტიმიზაცია"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9783,6 +9807,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10219,11 +10244,16 @@ msgid "Batch Rename"
msgstr "საქმის დამთხვევა"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "ჩანაცვლება"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10269,7 +10299,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10329,7 +10359,7 @@ msgid "Reset"
msgstr "ზუმის საწყისზე დაყენება"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12311,6 +12341,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 9b19450d58..d39f172539 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -23,7 +23,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-31 03:47+0000\n"
+"PO-Revision-Date: 2020-09-16 18:09+0000\n"
"Last-Translator: Ch. <ccwpc@hanmail.net>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
@@ -32,7 +32,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -541,6 +541,7 @@ msgid "Seconds"
msgstr "초"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "초당 프레임"
@@ -719,7 +720,7 @@ msgstr "대소문자 구분"
msgid "Whole Words"
msgstr "단어 단위로"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "바꾸기"
@@ -912,6 +913,11 @@ msgid "Signals"
msgstr "시그널"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "타일 필터"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "이 시그널의 모든 연결을 삭제할까요?"
@@ -949,7 +955,7 @@ msgid "Recent:"
msgstr "최근 기록:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "검색:"
@@ -1129,6 +1135,9 @@ msgstr "프로젝트 창립자"
msgid "Lead Developer"
msgstr "리드 개발자"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "프로젝트 매니저 "
@@ -1150,6 +1159,14 @@ msgid "Gold Sponsors"
msgstr "골드 스폰서"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "실버 스폰서"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "브론즈 스폰서"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "미니 스폰서"
@@ -1624,16 +1641,17 @@ 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 "파일 시스템과 가져오기 독"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "파일 시스템"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "독 가져오기"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1897,7 +1915,7 @@ msgstr "디렉토리 & 파일:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "미리 보기:"
@@ -2767,24 +2785,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"내보내거나 배포할 때, 결과 실행 파일은 디버깅을 위해 이 컴퓨터의 IP와 연결을 "
-"시도할 것입니다."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "네트워크 파일 시스템을 사용하여 작게 배포"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"이 설정을 켜면, 내보내거나 배포할 때 최소한의 실행 파일을 만듭니다.\n"
"이 경우, 실행 파일이 네트워크 너머에 있는 편집기의 파일 시스템을 사용합니"
@@ -2797,9 +2819,10 @@ msgid "Visible Collision Shapes"
msgstr "충돌 모양 보이기"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"이 설정을 켜면 게임을 실행하는 동안 (2D와 3D용) Collision 모양과 Raycast 노드"
"가 보이게 됩니다."
@@ -2809,23 +2832,26 @@ msgid "Visible Navigation"
msgstr "내비게이션 보이기"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"이 설정을 켜면, 게임을 실행하는 동안 Navigation 메시와 폴리곤이 보이게 됩니"
"다."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "씬 변경 사항 동기화"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"이 설정이 활성화된 경우, 편집기에서 씬을 수정하면 실행 중인 게임에도 반영됩니"
"다.\n"
@@ -2833,15 +2859,17 @@ msgstr ""
"적입니다."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "스크립트 변경 사항 동기화"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"이 설정이 활성화된 경우, 어떤 스크립트든 저장하면 실행중인 게임에도 새로고침"
"되어 반영됩니다.\n"
@@ -2905,7 +2933,7 @@ msgstr "도움말"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "검색"
@@ -3317,9 +3345,11 @@ msgid "Add Key/Value Pair"
msgstr "키/값 쌍 추가"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"이 플랫폼으로 실행할 수 있는 내보내기 프리셋이 없습니다.\n"
"내보내기 메뉴에서 실행할 수 있는 프리셋을 추가해주세요."
@@ -5077,7 +5107,7 @@ msgid "Bake Lightmaps"
msgstr "라이트맵 굽기"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "미리 보기"
@@ -7710,7 +7740,8 @@ msgid "New Animation"
msgstr "새 애니메이션"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "속도 (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9802,6 +9833,7 @@ msgstr ""
"Godot 프로젝트를 확인하기 위해 %s 폴더를 스캔할까요?\n"
"시간이 걸릴 수 있습니다."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "프로젝트 매니저"
@@ -10241,11 +10273,18 @@ msgid "Batch Rename"
msgstr "일괄 이름 바꾸기"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "바꾸기: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "접두사"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "접미사"
#: editor/rename_dialog.cpp
@@ -10293,7 +10332,8 @@ msgid "Per-level Counter"
msgstr "단계별 카운터"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "설정하면 각 그룹의 자식 노드의 카운터를 다시 시작합니다"
#: editor/rename_dialog.cpp
@@ -10353,7 +10393,8 @@ msgid "Reset"
msgstr "되돌리기"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "정규 표현식 오류"
#: editor/rename_dialog.cpp
@@ -12401,6 +12442,11 @@ msgstr ""
"GIProbe는 GLES2 비디오 드라이버에서 지원하지 않습니다.\n"
"대신 BakedLightmap을 사용하세요."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight의 각도를 90도 이상으로 잡게되면 그림자를 투영할 수 없습니다."
@@ -12700,6 +12746,16 @@ msgstr "Varying은 꼭짓점 함수에만 지정할 수 있습니다."
msgid "Constants cannot be modified."
msgstr "상수는 수정할 수 없습니다."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "파일 시스템과 가져오기 독"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "내보내거나 배포할 때, 결과 실행 파일은 디버깅을 위해 이 컴퓨터의 IP와 연결"
+#~ "을 시도할 것입니다."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "현재 씬이 아직 저장되지 않았습니다. 실행하기 전에 저장해주세요."
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 4d3884d5f8..c723a4ebb5 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -5,12 +5,13 @@
# Ignas Kiela <ignaskiela@super.lt>, 2017.
# Kornelijus <kornelijus.github@gmail.com>, 2017, 2018.
# Ignotas Gražys <ignotas.gr@gmail.com>, 2020.
+# Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-06 04:41+0000\n"
-"Last-Translator: Ignotas Gražys <ignotas.gr@gmail.com>\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
+"Last-Translator: Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>\n"
"Language-Team: Lithuanian <https://hosted.weblate.org/projects/godot-engine/"
"godot/lt/>\n"
"Language: lt\n"
@@ -19,12 +20,13 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n%10>=2 && (n%100<10 || n"
"%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-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 "Netinkamo tipo argumentas į convert(), naudoti TYPE_* konstantas."
+msgstr ""
+"Netinkamo tipo argumentas į funkciją convert(), naudokite TYPE_* konstantas."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -530,6 +532,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -712,7 +715,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -743,11 +746,11 @@ msgstr "Priartinti"
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Out"
-msgstr "Nutolinti"
+msgstr "Ištolinti"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Atstatyti Priartinimą"
+msgstr "Atstatyti priartinimą"
#: editor/code_editor.cpp
msgid "Warnings"
@@ -862,7 +865,7 @@ msgstr ""
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr "Uždaryti"
+msgstr "Užverti"
#: editor/connections_dialog.cpp
msgid "Connect"
@@ -913,6 +916,11 @@ msgid "Signals"
msgstr "Signalai"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrai..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -953,7 +961,7 @@ msgid "Recent:"
msgstr "Naujausi:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1127,6 +1135,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1148,6 +1159,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1615,16 +1634,16 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr ""
-
-#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Node Dock"
msgstr "Naujas pavadinimas:"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1901,7 +1920,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2745,22 +2764,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2769,8 +2792,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2779,32 +2802,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2865,7 +2888,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3036,15 +3059,15 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr "Atidaryti 2D Editorių"
+msgstr "Atverti 2D editorių"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr "Atidaryti 3D Editorių"
+msgstr "Atverti 3D editorių"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Atidaryti Skriptų Editorių"
+msgstr "Atverti skriptų editorių"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3274,7 +3297,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5066,7 +5090,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7711,7 +7735,7 @@ msgid "New Animation"
msgstr "Animacija"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9762,6 +9786,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10195,11 +10220,15 @@ msgid "Batch Rename"
msgstr "Animacija: Pervadinti Takelį"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10246,7 +10275,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10306,7 +10335,7 @@ msgid "Reset"
msgstr "Atstatyti Priartinimą"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10418,9 +10447,8 @@ msgid "Delete %d nodes and any children?"
msgstr "Ištrinti Efektą"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Ištrinti Efektą"
+msgstr "Ištrinti %d nodus?"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10431,9 +10459,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Ištrinti Efektą"
+msgstr "Ištrinti nodą \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -12287,6 +12314,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 2612b441c6..faf22e8f4e 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -529,6 +529,7 @@ msgid "Seconds"
msgstr "Sekundes"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -707,7 +708,7 @@ msgstr "Atrast Gadījumu"
msgid "Whole Words"
msgstr "Visu Vārdu"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Aizvietot"
@@ -900,6 +901,11 @@ msgid "Signals"
msgstr "Signāli"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "No Signāla:"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
"Vai esat drošs(ša), ka vēlaties noņemt visus savienojumus no šī signāla?"
@@ -938,7 +944,7 @@ msgid "Recent:"
msgstr "Nesenie:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Meklēt:"
@@ -1119,6 +1125,9 @@ msgstr "Projekta Dibinātāji"
msgid "Lead Developer"
msgstr "Galvenais Izstrādātājs"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projekta Menedžeris "
@@ -1140,6 +1149,16 @@ msgid "Gold Sponsors"
msgstr "Zelta Sponsori"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Sudraba Donors"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronzas Donors"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsori"
@@ -1609,15 +1628,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1880,7 +1899,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2706,22 +2725,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2730,8 +2753,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2740,32 +2763,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2825,7 +2848,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3225,7 +3248,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4949,7 +4973,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7559,7 +7583,7 @@ msgid "New Animation"
msgstr "Optimizēt animāciju"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9576,6 +9600,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10009,11 +10034,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Aizvietot: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10059,7 +10089,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10118,7 +10148,7 @@ msgid "Reset"
msgstr "Atiestatīt tālummaiņu"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12077,6 +12107,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 07a3bdae3c..d0e967f5bd 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -500,6 +500,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -678,7 +679,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -867,6 +868,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -904,7 +909,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1078,6 +1083,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1099,6 +1107,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1562,15 +1578,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1833,7 +1849,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2658,22 +2674,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2682,8 +2702,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2692,32 +2712,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2777,7 +2797,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3177,7 +3197,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4901,7 +4922,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7483,7 +7504,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9459,6 +9480,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9889,11 +9911,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9939,7 +9965,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -9997,7 +10023,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11926,6 +11952,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index aa7844d7ab..25ae499eac 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -510,6 +510,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -688,7 +689,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -877,6 +878,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -914,7 +919,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1088,6 +1093,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1109,6 +1117,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1572,15 +1588,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1843,7 +1859,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2670,22 +2686,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2694,8 +2714,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2704,32 +2724,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2789,7 +2809,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3189,7 +3209,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4916,7 +4937,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7499,7 +7520,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9475,6 +9496,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9905,11 +9927,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9955,7 +9981,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10013,7 +10039,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11943,6 +11969,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 043d7e643e..c17092697d 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -507,6 +507,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -685,7 +686,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -874,6 +875,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -911,7 +916,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1085,6 +1090,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1106,6 +1114,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1569,15 +1585,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1840,7 +1856,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2665,22 +2681,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2689,8 +2709,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2699,32 +2719,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2784,7 +2804,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3184,7 +3204,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4908,7 +4929,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7490,7 +7511,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9466,6 +9487,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9896,11 +9918,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9946,7 +9972,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10004,7 +10030,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11933,6 +11959,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index ad70f291ca..19d36c70cd 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -7,13 +7,14 @@
# Syaz Amirin <amirin123z@gmail.com>, 2018.
# Nafis Ibrahim <thepreciousnafis@gmail.com>, 2018.
# Muhammad Hazim bin Hafizalshah <muhammadhazimhafizalshah@gmail.com>, 2020.
+# keviinx <keviinx@yahoo.com>, 2020.
+# Keviindran Ramachandran <keviinx@yahoo.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-01-27 07:10+0000\n"
-"Last-Translator: Muhammad Hazim bin Hafizalshah "
-"<muhammadhazimhafizalshah@gmail.com>\n"
+"PO-Revision-Date: 2020-09-15 07:17+0000\n"
+"Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n"
"Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/"
"ms/>\n"
"Language: ms\n"
@@ -21,119 +22,118 @@ 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.11-dev\n"
+"X-Generator: Weblate 4.3-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 ""
+msgstr "Argumen jenis tidak sah untuk convert(), guna pemalar TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Menjangkakan rentetan dengan panjang 1 (satu watak)."
#: 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 "Bait tidak mencukupi untuk menyahkod bait, atau format tidak sah."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Input %i tidak sah (tidak lulus) dalam ungkapan"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr ""
+msgstr "self tidak boleh digunakan kerana instance adalah null (tidak lulus)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "Operan tidak sah untuk pengendali %s, %s dan %s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr ""
+msgstr "Indeks tidak sah untuk jenis %s untuk jenis asa %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "Indeks bernama tidak sah '%s' untuk jenis asa %s"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
-msgstr ""
+msgstr "Argumen tidak sah untuk binaan '%s'"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "Atas panggilan ke '%s':"
#: core/ustring.cpp
msgid "B"
-msgstr ""
+msgstr "B"
#: core/ustring.cpp
msgid "KiB"
-msgstr ""
+msgstr "KiB"
#: core/ustring.cpp
msgid "MiB"
-msgstr ""
+msgstr "MiB"
#: core/ustring.cpp
msgid "GiB"
-msgstr ""
+msgstr "GiB"
#: core/ustring.cpp
msgid "TiB"
-msgstr ""
+msgstr "TiB"
#: core/ustring.cpp
msgid "PiB"
-msgstr ""
+msgstr "PiB"
#: core/ustring.cpp
msgid "EiB"
-msgstr ""
+msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr ""
+msgstr "Bebas"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Seimbang"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr ""
+msgstr "Cermin"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
-msgstr ""
+msgstr "Masa:"
#: editor/animation_bezier_editor.cpp
msgid "Value:"
-msgstr ""
+msgstr "Nilai:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr ""
+msgstr "Masukkan Kunci di Sini"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Duplicate Selected Key(s)"
-msgstr "Anim Menduakan Kunci"
+msgstr "Gandakan Kunci Terpilih"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr ""
+msgstr "Padam Kunci Terpilih"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr ""
+msgstr "Tambah Titik Bezier"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr ""
+msgstr "Pindah Titik-titik Bezier"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -141,10 +141,9 @@ msgstr "Anim Menduakan Kunci"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr ""
+msgstr "Anim Padam Kunci"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Time"
msgstr "Anim Ubah Masa Keyframe"
@@ -154,7 +153,7 @@ msgstr "Anim Ubah Peralihan"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
-msgstr "Anim Ubah Penukaran"
+msgstr "Anim Ubah Perubahan"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
@@ -165,200 +164,192 @@ 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"
+msgstr "Anim Ubah Pelbagai Masa Keyframe"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transition"
-msgstr "Anim Ubah Peralihan"
+msgstr "Anim Ubah Pelbagai Peralihan"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transform"
-msgstr "Anim Ubah Penukaran"
+msgstr "Anim Ubah Pelbagai Penukaran"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Value"
-msgstr "Anim Ubah Nilai Keyframe"
+msgstr "Anim Ubah Pelbagai Nilai Keyframe"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Call"
-msgstr "Anim Ubah Panggilan"
+msgstr "Anim Ubah Pelbagai Panggilan"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr ""
+msgstr "Ubah Panjang Animasi"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Ubah Gelung Animasi"
#: editor/animation_track_editor.cpp
msgid "Property Track"
-msgstr ""
+msgstr "Trek Sifat"
#: editor/animation_track_editor.cpp
msgid "3D Transform Track"
-msgstr ""
+msgstr "Trek Transformasi 3D"
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
-msgstr ""
+msgstr "Trek Panggilan Kaedah"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
-msgstr ""
+msgstr "Trek Lengkung Bezier"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr ""
+msgstr "Trek Main balik Audio"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
-msgstr ""
+msgstr "Trek Main Balik Animasi"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr ""
+msgstr "Panjang animasi (bingkai)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr ""
+msgstr "Panjang animasi (saat)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track"
-msgstr "Anim Tambah Trek"
+msgstr "Tambah Trek"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
-msgstr ""
+msgstr "Gelung Animasi"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Functions:"
-msgstr ""
+msgstr "Fungsi:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr ""
+msgstr "Klip Audio:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "Klip Anim:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr ""
+msgstr "Tukar Laluan Trek"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr ""
+msgstr "Hidupkan / matikan trek ini."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr ""
+msgstr "Kemas kini Mod (Bagaimana sifat ini ditetapkan)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
-msgstr ""
+msgstr "Mod Interpolasi"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr ""
+msgstr "Mod Gelung Balut (Interpolat hujung dengan permulaan pada gelung)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove this track."
-msgstr "Buang Trek Anim"
+msgstr "Keluarkan trek ini."
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr ""
+msgstr "Masa (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr ""
+msgstr "Togol Trek Diaktifkan"
#: editor/animation_track_editor.cpp
msgid "Continuous"
-msgstr ""
+msgstr "Berterusan"
#: editor/animation_track_editor.cpp
msgid "Discrete"
-msgstr ""
+msgstr "Diskret"
#: editor/animation_track_editor.cpp
msgid "Trigger"
-msgstr ""
+msgstr "Pencetus"
#: editor/animation_track_editor.cpp
msgid "Capture"
-msgstr ""
+msgstr "Tangkap"
#: editor/animation_track_editor.cpp
msgid "Nearest"
-msgstr ""
+msgstr "Terdekat"
#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
msgid "Linear"
-msgstr ""
+msgstr "Linear"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr ""
+msgstr "Kubik"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr ""
+msgstr "Kepit Gelung Interp"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr ""
+msgstr "Balut Gelung Interp"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr ""
+msgstr "Masukkan Kunci"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "Anim Menduakan Kunci"
+msgstr "Menduakan Kunci"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
-msgstr ""
+msgstr "Padam Kunci"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr ""
+msgstr "Mod Tukar Kemas Kini Animasi"
#: editor/animation_track_editor.cpp
msgid "Change Animation Interpolation Mode"
-msgstr ""
+msgstr "Tukar Mod Interpolasi Animasi"
#: editor/animation_track_editor.cpp
msgid "Change Animation Loop Mode"
-msgstr ""
+msgstr "Tukar Mod Gelung Animasi"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
-msgstr "Buang Trek Anim"
+msgstr "Keluarkan Trek Anim"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr ""
+msgstr "Cipta trek BARU untuk %s dan masukkan kunci?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr ""
+msgstr "Cipta %d BARU trek dan masukkan kunci?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -370,40 +361,39 @@ msgstr ""
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Create"
-msgstr ""
+msgstr "Cipta"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
-msgstr ""
+msgstr "Masukkan Anim"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr ""
+msgstr "AnimationPlayer tidak animasikan dirinya sendiri, hanya pemain lain."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
-msgstr ""
+msgstr "Anim Cipta & Masukkan"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr ""
+msgstr "Anim Masukkan Trek & Kunci"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
-msgstr ""
+msgstr "Anim Masukkan Kunci"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Step"
-msgstr "Anim Ubah Peralihan"
+msgstr "Tukar Langkah Animasi"
#: editor/animation_track_editor.cpp
msgid "Rearrange Tracks"
-msgstr ""
+msgstr "Susun semula Trek"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr ""
+msgstr "Transformasi trek hanya berlaku kepada nod berasaskan Spatial."
#: editor/animation_track_editor.cpp
msgid ""
@@ -412,78 +402,82 @@ msgid ""
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
msgstr ""
+"Trek audio hanya boleh ditujukan kepada nod jenis:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "Trek animasi hanya dapat ditujukan kepada nod AnimationPlayer."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
msgstr ""
+"Pemain animasi tidak boleh animasikan dirinya sendiri, hanya pemain lain."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "Tidak boleh menambah trek baru tanpa satu akar"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "Trek tidak sah untuk Bezier (tiada sub-sifat yang sesuai)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "Anim Tambah Trek"
+msgstr "Tambah Trek Bezier"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr ""
+msgstr "Laluan trek tidak sah, maka tidak boleh menambahkan kunci."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
-msgstr ""
+msgstr "Trek bukan jenis Spatial, tidak boleh memasukkan kunci"
#: editor/animation_track_editor.cpp
msgid "Add Transform Track Key"
-msgstr ""
+msgstr "Tambah Kunci Trek Transformasi"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "Anim Tambah Trek"
+msgstr "Tambah Kunci Trek"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr ""
+msgstr "Laluan trek tidak sah, maka tidak boleh menambahkan kunci kaedah."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "Anim Tambah Trek"
+msgstr "Tambah Kunci Trek Kaedah"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
-msgstr ""
+msgstr "Kaedah tidak ditemui dalam objek: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
-msgstr ""
+msgstr "Kunci Gerak Anim"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
-msgstr ""
+msgstr "Papan klip kosong"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
-msgstr ""
+msgstr "Tampal Trek"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
-msgstr ""
+msgstr "Kunci Skala Anim"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
msgstr ""
+"Pilihan ini tidak berfungsi untuk pengeditan Bezier, kerana ia hanya satu "
+"trek."
#: editor/animation_track_editor.cpp
msgid ""
@@ -497,38 +491,48 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Animasi ini tergolong dalam adegan yang diimport, maka perubahan untuk trek "
+"yang diimport tidak akan disimpan.\n"
+"\n"
+"Untuk memberikan keupayaan untuk menambah trek tersuai, navigasi ke tetapan "
+"import adegan dan tetapkan\n"
+"\"Animasi > Simpanan\" ke \"Fail\", aktifkan \"Animasi > Simpan Trek Tersuai"
+"\", kemudian import semula.\n"
+"Sebagai alternatif, gunakan pratetap import yang mengimportkan animasi untuk "
+"memisahkan fail."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "Amaran: Mengedit animasi yang diimport"
#: editor/animation_track_editor.cpp
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr ""
+msgstr "Pilih nod AnimationPlayer untuk mencipta dan mengedit animasi."
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr ""
+msgstr "Hanya tunjukkan trek dari nod yang dipilih di pokok."
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
-msgstr ""
+msgstr "Kumpulkan trek mengikut nod atau memaparkannya sebagai senarai biasa."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr ""
+msgstr "Tangkap:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
-msgstr ""
+msgstr "Nilai langkah animasi."
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "Saat"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
-msgstr ""
+msgstr "FPS"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -538,108 +542,107 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit"
-msgstr ""
+msgstr "Edit"
#: editor/animation_track_editor.cpp
msgid "Animation properties."
-msgstr ""
+msgstr "Sifat animasi."
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr ""
+msgstr "Salin Trek"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
-msgstr ""
+msgstr "Pemilihan Skala"
#: editor/animation_track_editor.cpp
msgid "Scale From Cursor"
-msgstr ""
+msgstr "Skala Dari Kursor"
#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Duplicate Selection"
-msgstr ""
+msgstr "Menduakan Pilihan"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr ""
+msgstr "Menduakan Pindahan"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "Semua Pilihan"
+msgstr "Padam Pilihan"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr ""
+msgstr "Pergi ke Langkah Seterusnya"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr ""
+msgstr "Pergi ke Langkah Sebelumnya"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr ""
+msgstr "Optimumkan Animasi"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr ""
+msgstr "Bersihkan Animasi"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "Pilih nod yang akan dianimasikan:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "Guna Lengkung Bezier"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
-msgstr ""
+msgstr "Pengoptimum Anim."
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
-msgstr ""
+msgstr "Max. Ralat Linear:"
#: editor/animation_track_editor.cpp
msgid "Max. Angular Error:"
-msgstr ""
+msgstr "Max. Ralat Sudut:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr ""
+msgstr "Sudut Maksimum yang Boleh Dioptimumkan:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
-msgstr ""
+msgstr "Mengoptimumkan"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr ""
+msgstr "Keluarkan kunci yang tidak sah"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "Keluarkan trek yang tidak boleh diselesaikan dan kosong"
#: editor/animation_track_editor.cpp
msgid "Clean-up all animations"
-msgstr ""
+msgstr "Bersihkan semua animasi"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr ""
+msgstr "Bersihkan Animasi (TIDAK BOLEH BUAT ASAL!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
-msgstr ""
+msgstr "Bersihkan"
#: editor/animation_track_editor.cpp
msgid "Scale Ratio:"
-msgstr ""
+msgstr "Nisbah Skala:"
#: editor/animation_track_editor.cpp
msgid "Select Tracks to Copy"
-msgstr ""
+msgstr "Pilih Trek untuk Disalin"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -648,146 +651,146 @@ 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 "Salin"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "Semua Pilihan"
+msgstr "Pilih Semua/Tiada"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Anim Tambah Trek"
+msgstr "Tambah Klip Trek Audio"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "Tukar Klip Trek Audio Mula Offset"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "Tukar Klip Audio Trek Hujung Offset"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr ""
+msgstr "Ubah saiz Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr ""
+msgstr "Tukar Jenis Nilai Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr ""
+msgstr "Tukar Nilai Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr ""
+msgstr "Pergi ke Baris"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr ""
+msgstr "Nombor Baris:"
#: editor/code_editor.cpp
msgid "%d replaced."
-msgstr ""
+msgstr "%d telah diganti."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "%d padan."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
-msgstr ""
+msgstr "%d padan."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr ""
+msgstr "Kes Padan"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
-msgstr ""
+msgstr "Seluruh Perkataan"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
-msgstr ""
+msgstr "Ganti"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr ""
+msgstr "Ganti Semua"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr ""
+msgstr "Pilihan Sahaja"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
msgid "Standard"
-msgstr ""
+msgstr "Piawai"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr ""
+msgstr "Togol Panel Skrip"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom In"
-msgstr ""
+msgstr "Zum Masuk"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Out"
-msgstr ""
+msgstr "Zum Keluar"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr ""
+msgstr "Set Semula Zum"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr ""
+msgstr "Amaran"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr ""
+msgstr "Nombor baris dan lajur."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr ""
+msgstr "Kaedah dalam nod sasaran mesti ditentukan."
#: editor/connections_dialog.cpp
msgid "Method name must be a valid identifier."
-msgstr ""
+msgstr "Nama kaedah mestilah pengecam yang sah."
#: editor/connections_dialog.cpp
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
+"Kaedah sasaran tidak dijumpai. Tentukan kaedah yang sah atau lampirkan skrip "
+"ke nod sasaran."
#: editor/connections_dialog.cpp
msgid "Connect to Node:"
-msgstr ""
+msgstr "Sambung ke Nod:"
#: editor/connections_dialog.cpp
msgid "Connect to Script:"
-msgstr ""
+msgstr "Sambung ke Skrip:"
#: editor/connections_dialog.cpp
msgid "From Signal:"
-msgstr ""
+msgstr "Dari Isyarat:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "Adegan tidak mengandungi sebarang skrip."
#: 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 "Tambah"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
@@ -798,44 +801,46 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
-msgstr ""
+msgstr "Keluarkan"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr ""
+msgstr "Tambah Hujah Panggilan Tambahan:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr ""
+msgstr "Hujah Panggilan Tambahan:"
#: editor/connections_dialog.cpp
msgid "Receiver Method:"
-msgstr ""
+msgstr "Kaedah Penerima:"
#: editor/connections_dialog.cpp
msgid "Advanced"
-msgstr ""
+msgstr "Lanjutan"
#: editor/connections_dialog.cpp
msgid "Deferred"
-msgstr ""
+msgstr "Ditangguhkan"
#: editor/connections_dialog.cpp
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
msgstr ""
+"Mencegah isyarat, menyimpannya dalam barisan dan hanya menyalakannya pada "
+"waktu terbiar."
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr ""
+msgstr "Oneshot"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr ""
+msgstr "Putuskan isyarat selepas pelepasan pertama."
#: editor/connections_dialog.cpp
msgid "Cannot connect signal"
-msgstr ""
+msgstr "Tidak dapat menyambungkan isyarat"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -849,101 +854,109 @@ msgstr ""
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr ""
+msgstr "Tutup"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr ""
+msgstr "Sambung"
#: editor/connections_dialog.cpp
msgid "Signal:"
-msgstr ""
+msgstr "Isyarat:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr ""
+msgstr "Sambungkan '% s' ke '% s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr ""
+msgstr "Putuskan sambungan '% s' dari '% s'"
#: editor/connections_dialog.cpp
msgid "Disconnect all from signal: '%s'"
-msgstr ""
+msgstr "Putuskan semua sambungan dari isyarat: '% s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
-msgstr ""
+msgstr "Sambung ..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Disconnect"
-msgstr ""
+msgstr "Putuskan sambungan"
#: editor/connections_dialog.cpp
msgid "Connect a Signal to a Method"
-msgstr ""
+msgstr "Sambungkan Isyarat ke Kaedah"
#: editor/connections_dialog.cpp
msgid "Edit Connection:"
-msgstr ""
+msgstr "Edit Sambungan:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
msgstr ""
+"Adakah anda pasti anda mahu mengeluarkan semua sambungan dari isyarat \"% s"
+"\"?"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr ""
+msgstr "Isyarat"
+
+#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Dari Isyarat:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
+"Adakah anda pasti anda mahu mengeluarkan semua sambungan dari isyarat ini?"
#: editor/connections_dialog.cpp
msgid "Disconnect All"
-msgstr ""
+msgstr "Putuskan Semua"
#: editor/connections_dialog.cpp
msgid "Edit..."
-msgstr ""
+msgstr "Edit..."
#: editor/connections_dialog.cpp
msgid "Go To Method"
-msgstr ""
+msgstr "Pergi ke Kaedah"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr ""
+msgstr "Ubah Jenis %s"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
-msgstr ""
+msgstr "Ubah"
#: editor/create_dialog.cpp
msgid "Create New %s"
-msgstr ""
+msgstr "Cipta %s Baru"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
msgid "Favorites:"
-msgstr ""
+msgstr "Kegemaran:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
-msgstr ""
+msgstr "Terkini:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
-msgstr ""
+msgstr "Cari:"
#: 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 "Padanan:"
#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
#: editor/plugin_config_dialog.cpp
@@ -951,57 +964,61 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Description:"
-msgstr ""
+msgstr "Keterangan:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
-msgstr ""
+msgstr "Cari Penggantian Untuk:"
#: editor/dependency_editor.cpp
msgid "Dependencies For:"
-msgstr ""
+msgstr "Kebergantungan Untuk:"
#: editor/dependency_editor.cpp
msgid ""
"Scene '%s' is currently being edited.\n"
"Changes will only take effect when reloaded."
msgstr ""
+"Adegan '% s' kini sedang diedit.\n"
+"Perubahan hanya akan berlaku apabila dimuat semula."
#: editor/dependency_editor.cpp
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
msgstr ""
+"Sumber '% s' sedang digunakan.\n"
+"Perubahan hanya akan berlaku apabila dimuat semula."
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Dependencies"
-msgstr ""
+msgstr "Kebergantungan"
#: editor/dependency_editor.cpp
msgid "Resource"
-msgstr ""
+msgstr "Sumber"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
-msgstr ""
+msgstr "Laluan"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
-msgstr ""
+msgstr "Kebergantungan:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
-msgstr ""
+msgstr "Perbaiki Pecah"
#: editor/dependency_editor.cpp
msgid "Dependency Editor"
-msgstr ""
+msgstr "Editor Ketergantungan"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr ""
+msgstr "Cari Penggantian Sumber:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help_search.cpp editor/editor_node.cpp
@@ -1011,15 +1028,15 @@ msgstr ""
#: modules/visual_script/visual_script_property_selector.cpp
#: scene/gui/file_dialog.cpp
msgid "Open"
-msgstr ""
+msgstr "Buka"
#: editor/dependency_editor.cpp
msgid "Owners Of:"
-msgstr ""
+msgstr "Pemilik:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr ""
+msgstr "Alih keluar fail terpilih dari projek? (Tidak dapat dipulihkan)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1027,46 +1044,49 @@ msgid ""
"work.\n"
"Remove them anyway? (no undo)"
msgstr ""
+"Fail yang akan dikeluarkan diperlukan oleh sumber lain agar dapat "
+"berfungsi.\n"
+"Masih mahu keluarkan fail tersebut? (tidak boleh buat asal)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
-msgstr ""
+msgstr "Tidak boleh dialih keluar:"
#: editor/dependency_editor.cpp
msgid "Error loading:"
-msgstr ""
+msgstr "Ralat memuatkan:"
#: editor/dependency_editor.cpp
msgid "Load failed due to missing dependencies:"
-msgstr ""
+msgstr "Gagal memuat kerana kebergantungan hilang:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
-msgstr ""
+msgstr "Buka Bagaimanapun"
#: editor/dependency_editor.cpp
msgid "Which action should be taken?"
-msgstr ""
+msgstr "Tindakan apa yang harus diambil?"
#: editor/dependency_editor.cpp
msgid "Fix Dependencies"
-msgstr ""
+msgstr "Perbaiki Kebergantungan"
#: editor/dependency_editor.cpp
msgid "Errors loading!"
-msgstr ""
+msgstr "Ralat memuatkan!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr ""
+msgstr "Padamkan objek %d secara kekal? (Tidak boleh dibuat asal!)"
#: editor/dependency_editor.cpp
msgid "Show Dependencies"
-msgstr ""
+msgstr "Tunjuk Kebergantungan"
#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
-msgstr ""
+msgstr "Penjelajah Sumber Yatim"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -1074,79 +1094,92 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
msgid "Delete"
-msgstr ""
+msgstr "Padam"
#: editor/dependency_editor.cpp
msgid "Owns"
-msgstr ""
+msgstr "Memiliki"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr ""
+msgstr "Sumber Tanpa Hak Milik Eksplisit:"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Key"
-msgstr ""
+msgstr "Tukar Kunci Kamus"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Value"
-msgstr ""
+msgstr "Tukar Nilai Kamus"
#: editor/editor_about.cpp
msgid "Thanks from the Godot community!"
-msgstr ""
+msgstr "Terima kasih dari komuniti Godot!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr ""
+msgstr "Penyumbang Enjin Godot"
#: editor/editor_about.cpp
msgid "Project Founders"
-msgstr ""
+msgstr "Pengasas Projek"
#: editor/editor_about.cpp
msgid "Lead Developer"
-msgstr ""
+msgstr "Pemaju Utama"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr ""
+msgstr "Pengurus Projek "
#: editor/editor_about.cpp
msgid "Developers"
-msgstr ""
+msgstr "Pemaju"
#: editor/editor_about.cpp
msgid "Authors"
-msgstr ""
+msgstr "Pengarang"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr ""
+msgstr "Penaja Platinum"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr ""
+msgstr "Penaja Emas"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Penderma Perak"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Penderma Gangsa"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
-msgstr ""
+msgstr "Penaja Mini"
#: editor/editor_about.cpp
msgid "Gold Donors"
-msgstr ""
+msgstr "Penderma Emas"
#: editor/editor_about.cpp
msgid "Silver Donors"
-msgstr ""
+msgstr "Penderma Perak"
#: editor/editor_about.cpp
msgid "Bronze Donors"
-msgstr ""
+msgstr "Penderma Gangsa"
#: editor/editor_about.cpp
msgid "Donors"
-msgstr ""
+msgstr "Penderma"
#: editor/editor_about.cpp
msgid "License"
@@ -1154,7 +1187,7 @@ msgstr "Lesen"
#: editor/editor_about.cpp
msgid "Third-party Licenses"
-msgstr ""
+msgstr "Lesen Pihak Ketiga"
#: editor/editor_about.cpp
msgid ""
@@ -1163,389 +1196,398 @@ msgid ""
"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
+"Enjin Godot bergantung kepada beberapa perpustakaan sumber terbuka dan bebas "
+"pihak ketiga, semuanya serasi dengan syarat-syarat lesen MITnya. Berikut "
+"adalah senarai lengkap semua komponen pihak ketiga tersebut dengan "
+"pernyataan hak cipta dan syarat lesen masing-masing."
#: editor/editor_about.cpp
msgid "All Components"
-msgstr ""
+msgstr "Semua Komponen"
#: editor/editor_about.cpp
msgid "Components"
-msgstr ""
+msgstr "Komponen"
#: editor/editor_about.cpp
msgid "Licenses"
-msgstr ""
+msgstr "Lesen"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in ZIP format."
-msgstr ""
+msgstr "Ralat semasa membuka fail pakej, bukan dalam format ZIP."
#: editor/editor_asset_installer.cpp
msgid "%s (Already Exists)"
-msgstr ""
+msgstr "%s (Sudah Wujud)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
-msgstr ""
+msgstr "Nyahmampatkan Aset"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "Fail berikut gagal diekstrak dari pakej:"
#: editor/editor_asset_installer.cpp
msgid "And %s more files."
-msgstr ""
+msgstr "Dan sebanyak %s fail."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
-msgstr ""
+msgstr "Pakej berjaya dipasang!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr ""
+msgstr "Berjaya!"
#: editor/editor_asset_installer.cpp
msgid "Package Contents:"
-msgstr ""
+msgstr "Kandungan Pakej:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
-msgstr ""
+msgstr "Pasang"
#: editor/editor_asset_installer.cpp
msgid "Package Installer"
-msgstr ""
+msgstr "Pemasang Pakej"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
-msgstr ""
+msgstr "Pembesar suara"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
-msgstr ""
+msgstr "Tambah Kesan"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
-msgstr ""
+msgstr "Namakan Semula Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Change Audio Bus Volume"
-msgstr ""
+msgstr "Tukar Kelantangan Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr ""
+msgstr "Togol Bas Audio Solo"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr ""
+msgstr "Togol Senyap Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr ""
+msgstr "Togol Kesan Pintasan Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr ""
+msgstr "Pilih Hantar Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr ""
+msgstr "Tambah Kesan Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr ""
+msgstr "Alih Kesan Bas"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr ""
+msgstr "Padam Kesan Bas"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
-msgstr ""
+msgstr "Seret & lepas untuk menyusun semula."
#: editor/editor_audio_buses.cpp
msgid "Solo"
-msgstr ""
+msgstr "Solo"
#: editor/editor_audio_buses.cpp
msgid "Mute"
-msgstr ""
+msgstr "Bisu"
#: editor/editor_audio_buses.cpp
msgid "Bypass"
-msgstr ""
+msgstr "Pintas"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
-msgstr ""
+msgstr "Pilihan bas"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr ""
+msgstr "Pendua"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
-msgstr ""
+msgstr "Tetapkan Semula Kelantangan"
#: editor/editor_audio_buses.cpp
msgid "Delete Effect"
-msgstr ""
+msgstr "Padam Kesan"
#: editor/editor_audio_buses.cpp
msgid "Audio"
-msgstr ""
+msgstr "Audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "Tambah Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "Bas induk tidak boleh dipadamkan!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "Padam Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr ""
+msgstr "Pendua Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr ""
+msgstr "Tetapkan Semula Kelantangan Bas"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
-msgstr ""
+msgstr "Pindah Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "Simpan Susun Atur Bas Audio Sebagai..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
-msgstr ""
+msgstr "Lokasi untuk Susun Atur Baru..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "Buka Susun Atur Bas Audio"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
-msgstr ""
+msgstr "Tiada fail '%s'."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
-msgstr ""
+msgstr "Susun atur"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "Fail tidak sah, bukan susun atur bas audio."
#: editor/editor_audio_buses.cpp
msgid "Error saving file: %s"
-msgstr ""
+msgstr "Ralat semasa menyimpan fail: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "Tambah Bas"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
-msgstr ""
+msgstr "Tambah Bas Audio baru ke susun atur ini."
#: 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 ""
+msgstr "Memuatkan"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr ""
+msgstr "Muatkan Susun Atur Bas yang sedia ada."
#: editor/editor_audio_buses.cpp
msgid "Save As"
-msgstr ""
+msgstr "Simpan sebagai"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "Simpan Susun Atur Bas ini ke fail."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
-msgstr ""
+msgstr "Muatkan Lalai"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "Muatkan Susun Atur Bas lalai."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "Cipta Susun Atur Bas baru."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr ""
+msgstr "Nama tidak sah."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
-msgstr ""
+msgstr "Watak yang sah:"
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing engine class name."
-msgstr ""
+msgstr "Tidak boleh bertembung dengan nama kelas engin yang telah wujud."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing built-in type name."
msgstr ""
+"Tidak boleh bertembung dengan nama jenis terbina dalam yang telah wujud."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing global constant name."
-msgstr ""
+msgstr "Tidak boleh bertembung dengan nama pemalar global yang telah wujud."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "Kata kunci tidak boleh digunakan sebagai nama autoload."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "Autoload '%s' sudah wujud!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr ""
+msgstr "Namakan Semula Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr ""
+msgstr "Togol Global Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
-msgstr ""
+msgstr "Pindah Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Remove Autoload"
-msgstr ""
+msgstr "Keluarkan Autoload"
#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
-msgstr ""
+msgstr "Aktifkan"
#: editor/editor_autoload_settings.cpp
msgid "Rearrange Autoloads"
-msgstr ""
+msgstr "Susun Semula Autoload"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr ""
+msgstr "Tidak boleh menambahkan autoload:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
-msgstr ""
+msgstr "Tambah AutoLoad"
#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
msgid "Path:"
-msgstr ""
+msgstr "Laluan:"
#: editor/editor_autoload_settings.cpp
msgid "Node Name:"
-msgstr ""
+msgstr "Nama Nod:"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
#: editor/editor_profiler.cpp editor/project_manager.cpp
#: editor/settings_config_dialog.cpp
msgid "Name"
-msgstr ""
+msgstr "Nama"
#: editor/editor_autoload_settings.cpp
msgid "Singleton"
-msgstr ""
+msgstr "Singleton"
#: editor/editor_data.cpp editor/inspector_dock.cpp
msgid "Paste Params"
-msgstr ""
+msgstr "Tampal Param"
#: editor/editor_data.cpp
msgid "Updating Scene"
-msgstr ""
+msgstr "Mengemaskini Adegan"
#: editor/editor_data.cpp
msgid "Storing local changes..."
-msgstr ""
+msgstr "Menyimpan perubahan tempatan..."
#: editor/editor_data.cpp
msgid "Updating scene..."
-msgstr ""
+msgstr "Mengemaskini adegan..."
#: editor/editor_data.cpp editor/editor_properties.cpp
msgid "[empty]"
-msgstr ""
+msgstr "[kosong]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "[tidak disimpan]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first."
-msgstr ""
+msgstr "Sila pilih direktori asas terlebih dahulu."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
-msgstr ""
+msgstr "Pilih Direktori"
#: 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 ""
+msgstr "Cipta Folder"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp
msgid "Name:"
-msgstr ""
+msgstr "Nama:"
#: 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 ""
+msgstr "Tidak dapat mencipta folder."
#: editor/editor_dir_dialog.cpp
msgid "Choose"
-msgstr ""
+msgstr "Pilih"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr ""
+msgstr "Menyimpan Fail:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "Tiada templat eksport ditemui di laluan yang dijangkakan:"
#: editor/editor_export.cpp
msgid "Packing"
-msgstr ""
+msgstr "Pembungkusan"
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"Platform sasaran memerlukan pemampatan tekstur 'ETC' untuk GLES2. Aktifkan "
+"'Import Etc' dalam Tetapan Projek."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"Platform sasaran memerlukan pemampatan tekstur 'ETC2' untuk GLES3. Aktifkan "
+"'Import Etc 2' dalam Tetapan Projek."
#: editor/editor_export.cpp
msgid ""
@@ -1554,508 +1596,520 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"Platform sasaran memerlukan pemampatan tekstur 'ETC' untuk sandaran pemandu "
+"ke GLES2.\n"
+"Aktifkan 'Import Etc' dalam Tetapan Projek, atau nyahaktifkan 'Driver "
+"Fallback Enabled'."
#: 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 ""
+msgstr "Templat nyahpepijat tersuai tidak dijumpai."
#: 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 ""
+msgstr "Templat pelepasan tersuai tidak dijumpai."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
-msgstr ""
+msgstr "Fail templat tidak dijumpai:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"Pada eksport 32-bit PCK terbenam tidak boleh lebih besar daripada 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
-msgstr ""
+msgstr "Editor 3D"
#: editor/editor_feature_profile.cpp
msgid "Script Editor"
-msgstr ""
+msgstr "Editor Skrip"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr ""
+msgstr "Perpustakaan Aset"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
-msgstr ""
+msgstr "Penyuntingan Pokok Adegan"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr ""
+msgid "Node Dock"
+msgstr "Dok nod"
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
-msgstr ""
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistem Fail dan Dok Import"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr ""
+msgid "Import Dock"
+msgstr "Import Dok"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
-msgstr ""
+msgstr "Padamkan profil '%s'? (tidak boleh buat asal)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "Profil mestilah nama fail yang sah dan tidak boleh mengandungi '.'"
#: editor/editor_feature_profile.cpp
msgid "Profile with this name already exists."
-msgstr ""
+msgstr "Profil dengan nama ini sudah wujud."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(Editor Dinyahaktifkan, Ciri-ciri Dinyahaktifkan)"
#: editor/editor_feature_profile.cpp
msgid "(Properties Disabled)"
-msgstr ""
+msgstr "(Ciri-ciri dinyahaktif)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "Tidak Aktif"
+msgstr "(Editor Dinyahaktif)"
#: editor/editor_feature_profile.cpp
msgid "Class Options:"
-msgstr ""
+msgstr "Pilihan Kelas:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
-msgstr ""
+msgstr "Aktifkan Editor Kontekstual"
#: editor/editor_feature_profile.cpp
msgid "Enabled Properties:"
-msgstr ""
+msgstr "Ciri-ciri Diaktifkan:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
-msgstr ""
+msgstr "Ciri Diaktifkan:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Classes:"
-msgstr ""
+msgstr "Kelas Diaktifkan:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "Format fail '%s' tidak sah, import dibatalkan."
#: editor/editor_feature_profile.cpp
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
+"Profil '%s' sudah wujud. Keluarkannya terlebih dahulu sebelum mengimport, "
+"import dibatalkan."
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
-msgstr ""
+msgstr "Ralat menyimpan profil ke laluan: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "Nyahtetap"
#: editor/editor_feature_profile.cpp
msgid "Current Profile:"
-msgstr ""
+msgstr "Profil Semasa:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
-msgstr ""
+msgstr "Buat Semasa"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "New"
-msgstr ""
+msgstr "Baru"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr ""
+msgstr "Import"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
-msgstr ""
+msgstr "Eksport"
#: editor/editor_feature_profile.cpp
msgid "Available Profiles:"
-msgstr ""
+msgstr "Profil yang ada:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
-msgstr ""
+msgstr "Pilihan Kelas"
#: editor/editor_feature_profile.cpp
msgid "New profile name:"
-msgstr ""
+msgstr "Nama profil baru:"
#: editor/editor_feature_profile.cpp
msgid "Erase Profile"
-msgstr ""
+msgstr "Padam Profil"
#: editor/editor_feature_profile.cpp
msgid "Godot Feature Profile"
-msgstr ""
+msgstr "Profil Ciri Godot"
#: editor/editor_feature_profile.cpp
msgid "Import Profile(s)"
-msgstr ""
+msgstr "Import Profil"
#: editor/editor_feature_profile.cpp
msgid "Export Profile"
-msgstr ""
+msgstr "Eksport Profil"
#: editor/editor_feature_profile.cpp
msgid "Manage Editor Feature Profiles"
-msgstr ""
+msgstr "Urus Profil Ciri Editor"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
-msgstr ""
+msgstr "Pilih Folder Semasa"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
-msgstr ""
+msgstr "Fail Wujud, Tulis Ganti?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select This Folder"
-msgstr ""
+msgstr "Pilih Folder Ini"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr ""
+msgstr "Salin Laluan"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Open in File Manager"
-msgstr ""
+msgstr "Buka dalam Pengurus Fail"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
msgid "Show in File Manager"
-msgstr ""
+msgstr "Tunjukkan dalam Pengurus Fail"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "New Folder..."
-msgstr ""
+msgstr "Folder Baru..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
-msgstr ""
+msgstr "Muat Semula"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "Semua Dikenali"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
-msgstr ""
+msgstr "Semua Fail (*)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
-msgstr ""
+msgstr "Buka Fail"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
-msgstr ""
+msgstr "Buka Fail"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a Directory"
-msgstr ""
+msgstr "Buka Direktori"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File or Directory"
-msgstr ""
+msgstr "Buka Fail atau Direktori"
#: 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 ""
+msgstr "Simpan"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Save a File"
-msgstr ""
+msgstr "Simpan Fail"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr ""
+msgstr "Pergi Balik"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr ""
+msgstr "Pergi ke Hadapan"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr ""
+msgstr "Pergi Atas"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr ""
+msgstr "Togol Fail Tersembunyi"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr ""
+msgstr "Togol Kegemaran"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr ""
+msgstr "Togol Mod"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr ""
+msgstr "Laluan Fokus"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr ""
+msgstr "Pindah Kegemaran ke Atas"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr ""
+msgstr "Pindah Kegemaran ke Bawah"
#: editor/editor_file_dialog.cpp
msgid "Go to previous folder."
-msgstr ""
+msgstr "Pergi ke folder sebelumnya."
#: editor/editor_file_dialog.cpp
msgid "Go to next folder."
-msgstr ""
+msgstr "Pergi ke folder seterusnya."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
-msgstr ""
+msgstr "Pergi ke folder induk."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Refresh files."
-msgstr ""
+msgstr "Muat semula fail."
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
-msgstr ""
+msgstr "(Nyah)kegemaran folder semasa."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
-msgstr ""
+msgstr "Togol keterlihatan fail tersembunyi."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
-msgstr ""
+msgstr "Lihat barang sebagai grid gambar kecil."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a list."
-msgstr ""
+msgstr "Lihat barang sebagai senarai."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
-msgstr ""
+msgstr "Direktori & Fail:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
-msgstr ""
+msgstr "Pratonton:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File:"
-msgstr ""
+msgstr "Fail:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Must use a valid extension."
-msgstr ""
+msgstr "Mesti menggunakan sambungan yang sah."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr ""
+msgstr "Sumber Imbas"
#: editor/editor_file_system.cpp
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Terdapat beberapa pengimport untuk pelbagai jenis yang menunjukkan ke fail "
+"%s, import dibatalkan"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr ""
+msgstr "Mengimport (Semula) Aset"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
-msgstr ""
+msgstr "Atas"
#: editor/editor_help.cpp
msgid "Class:"
-msgstr ""
+msgstr "Kelas:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
#: editor/script_create_dialog.cpp
msgid "Inherits:"
-msgstr ""
+msgstr "Mewarisi:"
#: editor/editor_help.cpp
msgid "Inherited by:"
-msgstr ""
+msgstr "Diwarisi oleh:"
#: editor/editor_help.cpp
msgid "Description"
-msgstr ""
+msgstr "Keterangan"
#: editor/editor_help.cpp
msgid "Online Tutorials"
-msgstr ""
+msgstr "Tutorial Dalam Talian"
#: editor/editor_help.cpp
msgid "Properties"
-msgstr ""
+msgstr "Sifat"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "ganti:"
#: editor/editor_help.cpp
msgid "default:"
-msgstr ""
+msgstr "lalai:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr ""
+msgstr "Kaedah"
#: editor/editor_help.cpp
msgid "Theme Properties"
-msgstr ""
+msgstr "Sifat Tema"
#: editor/editor_help.cpp
msgid "Enumerations"
-msgstr ""
+msgstr "Penghitungan"
#: editor/editor_help.cpp
msgid "Constants"
-msgstr ""
+msgstr "Pemalar"
#: editor/editor_help.cpp
msgid "Property Descriptions"
-msgstr ""
+msgstr "Penerangan Sifat"
#: editor/editor_help.cpp
msgid "(value)"
-msgstr ""
+msgstr "(nilai)"
#: 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 ""
+"Tiada keterangan untuk sifat ini. Tolong bantu kami dengan [color=$color]"
+"[url=$url]menyumbang satu[/url][/color]!"
#: editor/editor_help.cpp
msgid "Method Descriptions"
-msgstr ""
+msgstr "Penerangan Kaedah"
#: 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 ""
+"Tiada keterangan untuk kaedah ini. Tolong bantu kami dengan [color=$color]"
+"[url=$url]menyumbang satu[/url][/color]!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr ""
+msgstr "Cari Bantuan"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
-msgstr ""
+msgstr "Kesensitifan Huruf"
#: editor/editor_help_search.cpp
msgid "Show Hierarchy"
-msgstr ""
+msgstr "Tunjuk Hierarki"
#: editor/editor_help_search.cpp
msgid "Display All"
-msgstr ""
+msgstr "Paparkan Semua"
#: editor/editor_help_search.cpp
msgid "Classes Only"
-msgstr ""
+msgstr "Kelas Sahaja"
#: editor/editor_help_search.cpp
msgid "Methods Only"
-msgstr ""
+msgstr "Kaedah Sahaja"
#: editor/editor_help_search.cpp
msgid "Signals Only"
-msgstr ""
+msgstr "Isyarat Sahaja"
#: editor/editor_help_search.cpp
msgid "Constants Only"
-msgstr ""
+msgstr "Pemalar Sahaja"
#: editor/editor_help_search.cpp
msgid "Properties Only"
-msgstr ""
+msgstr "Sifat Sahaja"
#: editor/editor_help_search.cpp
msgid "Theme Properties Only"
-msgstr ""
+msgstr "Sifat Tema Sahaja"
#: editor/editor_help_search.cpp
msgid "Member Type"
-msgstr ""
+msgstr "Jenis Ahli"
#: editor/editor_help_search.cpp
msgid "Class"
-msgstr ""
+msgstr "Kelas"
#: editor/editor_help_search.cpp
msgid "Method"
-msgstr ""
+msgstr "Kaedah"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
msgid "Signal"
-msgstr ""
+msgstr "Isyarat"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr ""
+msgstr "Pemalar"
#: editor/editor_help_search.cpp
msgid "Property"
-msgstr ""
+msgstr "Sifat"
#: editor/editor_help_search.cpp
msgid "Theme Property"
-msgstr ""
+msgstr "Sifat Tema"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "Sifat:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr ""
+msgstr "Tetapkan"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "Tetapkan Pelbagai:"
#: editor/editor_log.cpp
msgid "Output:"
-msgstr ""
+msgstr "Keluaran:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "Semua Pilihan"
+msgstr "Salin Pilihan"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2065,176 +2119,184 @@ msgstr "Semua Pilihan"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr ""
+msgstr "Kosongkan"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr ""
+msgstr "Kosongkan Keluaran"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
msgid "Stop"
-msgstr ""
+msgstr "Hentikan"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
msgid "Start"
-msgstr ""
+msgstr "Mulakan"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
msgid "Down"
-msgstr ""
+msgstr "Bawah"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "Atas"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
-msgstr ""
+msgstr "Nod"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "RPC masuk"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "RSET masuk"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "RPC Keluar"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "RSET Keluar"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "Tetingkap Baru"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "Sumber yang diimport tidak dapat disimpan."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "OK"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "Ralat semasa menyimpan sumber!"
#: 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 ""
+"Sumber ini tidak dapat disimpan kerana tidak tergolong dalam adegan yang "
+"diedit. Jadikannya unik terlebih dahulu."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
-msgstr ""
+msgstr "Simpan Sumber Sebagai..."
#: editor/editor_node.cpp
msgid "Can't open file for writing:"
-msgstr ""
+msgstr "Tidak dapat membuka fail untuk ditulis:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr ""
+msgstr "Format fail yang diminta tidak diketahui:"
#: editor/editor_node.cpp
msgid "Error while saving."
-msgstr ""
+msgstr "Ralat semasa menyimpan."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
msgstr ""
+"Tidak dapat membuka '% s'. Fail mungkin telah dipindahkan atau dipadam."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr ""
+msgstr "Ralat semasa menghuraikan '%s'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "Penghujung fail '%s' tidak dijangka."
#: editor/editor_node.cpp
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "Hilang '%s' atau kebergantungannya."
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
-msgstr ""
+msgstr "Ralat semasa memuatkan '%s'."
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr ""
+msgstr "Menyimpan Adegan"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr ""
+msgstr "Menganalisis"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr ""
+msgstr "Mencipta Gambar Kecil"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr ""
+msgstr "Operasi ini tidak boleh dilakukan tanpa akar pokok."
#: 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 ""
+"Adegan ini tidak dapat disimpan kerana terdapat penyertaan yang berbentuk "
+"siklik.\n"
+"Sila selesaikan dan kemudian cuba simpan semula."
#: editor/editor_node.cpp
msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
msgstr ""
+"Tidak dapat menyimpan adegan. Kemungkinan kebergantungan (instance atau "
+"warisan) tidak dapat dipenuhi."
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "Tidak boleh tulis ganti adegan yang masih terbuka!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr ""
+msgstr "Tidak dapat memuatkan MeshLibrary untuk penggabungan!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "Ralat menyimpan MeshLibrary!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr ""
+msgstr "Tidak boleh memuatkan TileSet untuk penggabungan!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr ""
+msgstr "Ralat semasa menyimpan TileSet!"
#: editor/editor_node.cpp
msgid "Error trying to save layout!"
-msgstr ""
+msgstr "Ralat semasa menyimpan susun atur!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr ""
+msgstr "Susun atur lalai telah diganti."
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr ""
+msgstr "Nama susun atur tidak dijumpai!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
-msgstr ""
+msgstr "Tata letak lalai telah dipulihkan ke tetapan asas."
#: editor/editor_node.cpp
msgid ""
@@ -2242,18 +2304,26 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"Sumber ini tergolong dalam adegan yang diimport, maka ia tidak dapat "
+"diedit.\n"
+"Sila baca dokumentasi yang berkaitan dengan pengimportan adegan untuk lebih "
+"memahami aliran kerja ini."
#: 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 ""
+"Sumber ini tergolong dalam adegan yang di-instance atau diwarisi.\n"
+"Perubahan tidak akan disimpan semasa menyimpan adegan semasa."
#: editor/editor_node.cpp
msgid ""
"This resource was imported, so it's not editable. Change its settings in the "
"import panel and then re-import."
msgstr ""
+"Sumber ini telah diimport, maka ia tidak dapat diedit. Ubah tetapannya di "
+"panel import dan kemudian import semula."
#: editor/editor_node.cpp
msgid ""
@@ -2262,6 +2332,10 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"Adegan ini telah diimport, maka perubahan kepada ia tidak akan disimpan.\n"
+"Instance-kan ia atau mewarisi akan membenarkan perubahan dibuat padanya.\n"
+"Sila baca dokumentasi yang berkaitan dengan pengimportan adegan untuk lebih "
+"memahami aliran kerja ini."
#: editor/editor_node.cpp
msgid ""
@@ -2269,150 +2343,158 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
+"Ini adalah objek terpencil, maka perubahan padanya tidak akan disimpan.\n"
+"Sila baca dokumentasi yang berkaitan dengan penyahpepijatan untuk lebih "
+"memahami aliran kerja ini."
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
-msgstr ""
+msgstr "Tiada adegan yang didefinisikan untuk dijalankan."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
-msgstr ""
+msgstr "Tidak dapat memulakan subproses!"
#: editor/editor_node.cpp editor/filesystem_dock.cpp
msgid "Open Scene"
-msgstr ""
+msgstr "Buka Adegan"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr ""
+msgstr "Buka Adegan Asas"
#: editor/editor_node.cpp
msgid "Quick Open..."
-msgstr ""
+msgstr "Buka Cepat..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr ""
+msgstr "Buka Cepat Adegan..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr ""
+msgstr "Buka Cepat Skrip..."
#: editor/editor_node.cpp
msgid "Save & Close"
-msgstr ""
+msgstr "Simpan & Tutup"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
-msgstr ""
+msgstr "Simpan perubahan pada '%s' sebelum menutup?"
#: editor/editor_node.cpp
msgid "Saved %s modified resource(s)."
-msgstr ""
+msgstr "Sumber %s yang diubahsuai telah disimpan."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "Nod akar diperlukan untuk menyimpan adegan."
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr ""
+msgstr "Simpan Adegan Sebagai..."
#: editor/editor_node.cpp
msgid "No"
-msgstr ""
+msgstr "Tidak"
#: editor/editor_node.cpp
msgid "Yes"
-msgstr ""
+msgstr "Ya"
#: editor/editor_node.cpp
msgid "This scene has never been saved. Save before running?"
-msgstr ""
+msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
-msgstr ""
+msgstr "Operasi ini tidak boleh dilakukan tanpa adegan."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "Eksport Perpustakaan Mesh"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr ""
+msgstr "Operasi ini tidak boleh dilakukan tanpa nod akar."
#: editor/editor_node.cpp
msgid "Export Tile Set"
-msgstr ""
+msgstr "Eksport Tile Set"
#: editor/editor_node.cpp
msgid "This operation can't be done without a selected node."
-msgstr ""
+msgstr "Operasi ini tidak dapat dilakukan tanpa nod terpilih."
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr ""
+msgstr "Adegan semasa tidak disimpan. Masih buka?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr ""
+msgstr "Tidak dapat memuatkan semula adegan yang tidak pernah disimpan."
#: editor/editor_node.cpp
msgid "Reload Saved Scene"
-msgstr ""
+msgstr "Muatkan semula Adegan yang Disimpan"
#: editor/editor_node.cpp
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"Adegan semasa mempunyai perubahan yang belum disimpan.\n"
+"Masih muat semula adegan yang telah disimpan? Tindakan ini tidak boleh "
+"dibuat asal."
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
-msgstr ""
+msgstr "Jalan Cepat Adegan..."
#: editor/editor_node.cpp
msgid "Quit"
-msgstr ""
+msgstr "Keluar"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr ""
+msgstr "Keluar dari editor?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
-msgstr ""
+msgstr "Buka Pengurus Projek?"
#: editor/editor_node.cpp
msgid "Save & Quit"
-msgstr ""
+msgstr "Simpan & Keluar"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr ""
+msgstr "Simpan perubahan pada adegan berikut sebelum keluar?"
#: editor/editor_node.cpp
msgid "Save changes the following scene(s) before opening Project Manager?"
-msgstr ""
+msgstr "Simpan perubahan adegan berikut sebelum membuka Pengurus Projek?"
#: editor/editor_node.cpp
msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
+"Pilihan ini tidak digunakan lagi. Situasi di mana penyegaran mesti dipaksa "
+"sekarang dianggap sebagai pepijat. Sila laporkan."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
-msgstr ""
+msgstr "Pilih Adegan Utama"
#: editor/editor_node.cpp
msgid "Close Scene"
-msgstr ""
+msgstr "Tutup Adegan"
#: editor/editor_node.cpp
msgid "Reopen Closed Scene"
-msgstr ""
+msgstr "Buka Semula Adegan Tertutup"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2691,22 +2773,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2715,8 +2801,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2725,32 +2811,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2758,9 +2844,8 @@ msgid "Editor"
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Set Peralihan ke:"
+msgstr "Tetapan Editor..."
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2811,7 +2896,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3211,7 +3296,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4064,9 +4150,8 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Animation Point"
-msgstr "Set Peralihan ke:"
+msgstr "Tambah Titik Animasi"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Remove BlendSpace1D Point"
@@ -4209,9 +4294,8 @@ msgid "Nodes Disconnected"
msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "Set Peralihan ke:"
+msgstr "Tetapkan Animasi"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4391,9 +4475,8 @@ msgid "Animation"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "Set Peralihan ke:"
+msgstr "Sunting Peralihan..."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Open in Inspector"
@@ -4491,14 +4574,12 @@ msgid "Move Node"
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Set Peralihan ke:"
+msgstr "Peralihan wujud!"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "Set Peralihan ke:"
+msgstr "Tambah Peralihan"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -4538,9 +4619,8 @@ msgid "Node Removed"
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "Set Peralihan ke:"
+msgstr "Peralihan Dikeluarkan"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
@@ -4574,9 +4654,8 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition: "
-msgstr "Set Peralihan ke:"
+msgstr "Peralihan: "
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Play Mode:"
@@ -4948,7 +5027,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -5621,9 +5700,8 @@ msgid "Load Curve Preset"
msgstr ""
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
-msgstr "Set Peralihan ke:"
+msgstr "Tambah Titik"
#: editor/plugins/curve_editor_plugin.cpp
#, fuzzy
@@ -7540,7 +7618,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8065,9 +8143,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete selected Rect."
-msgstr "Semua Pilihan"
+msgstr "Padam Rect yang dipilih."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8076,9 +8153,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "Semua Pilihan"
+msgstr "Padam poligon."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8477,9 +8553,8 @@ msgid "Color constant."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Anim Ubah Penukaran"
+msgstr "Warna seragam."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
@@ -8822,9 +8897,8 @@ msgid "Scalar constant."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Anim Ubah Penukaran"
+msgstr "Seragam skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
@@ -9532,6 +9606,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9963,11 +10038,16 @@ msgid "Batch Rename"
msgstr "Ubah Nama Trek Anim"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Ganti"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10013,7 +10093,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10071,7 +10151,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10177,14 +10257,12 @@ msgid "Make node as Root"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Semua Pilihan"
+msgstr "Padamkan nod %d dan mana-mana kanak-kanak?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Semua Pilihan"
+msgstr "Padam nod %d?"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10195,9 +10273,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Semua Pilihan"
+msgstr "Padam nod \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -11172,9 +11249,8 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "Set Peralihan ke:"
+msgstr "Tambah Port Input"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Output Port"
@@ -11419,9 +11495,8 @@ msgid "Add Nodes..."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "Semua Pilihan"
+msgstr "Tambah fungsi..."
#: modules/visual_script/visual_script_editor.cpp
msgid "function_name"
@@ -12014,6 +12089,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index dbad564d9a..33758ee5cd 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -555,6 +555,7 @@ msgid "Seconds"
msgstr "Sekunder"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -744,7 +745,7 @@ msgstr "Match Tilfelle"
msgid "Whole Words"
msgstr "Hele Ord"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Erstatt"
@@ -949,6 +950,11 @@ msgid "Signals"
msgstr "Signaler"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrer Filer..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
"Er du sikker på at du ønsker å fjerne alle koblinger fra dette signalet?"
@@ -990,7 +996,7 @@ msgid "Recent:"
msgstr "Nylige:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Søk:"
@@ -1178,6 +1184,9 @@ msgstr "Prosjektgrunnleggere"
msgid "Lead Developer"
msgstr "Utviklingsleder"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Prosjektstyring "
@@ -1199,6 +1208,16 @@ msgid "Gold Sponsors"
msgstr "Gullsponsorer"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Sølvdonorer"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronsedonorer"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Minisponsorer"
@@ -1696,21 +1715,21 @@ msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Importer"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "Flytt Modus"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "FilSystem"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "Importer"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "Erstatt Alle"
@@ -1997,7 +2016,7 @@ msgstr "Mapper og Filer:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Forhåndsvisning:"
@@ -2914,26 +2933,29 @@ msgid "Deploy with Remote Debug"
msgstr "Distribuer med ekstern feilsøking"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Ved eksportering eller deploying, den følgende kjørbare filen vil prøve å "
-"koble til IP'en til denne datamaskinen for å bli debugget."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Liten utrulling med Network FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Når dette alternativet er aktivert, eksportering eller distribuering vil "
"produsere en kjørbar fil.\n"
@@ -2946,9 +2968,10 @@ msgid "Visible Collision Shapes"
msgstr "Synlige kollisjons-former"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Kollisjons-former eller raycast-noder (for 2D og 3D) vil være synlige under "
"kjøring av spill om denne innstillingen er aktivert."
@@ -2958,23 +2981,26 @@ msgid "Visible Navigation"
msgstr "Synlig navigasjon"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigasjons-maske og polygoner vil være synlig under kjøring av spill om "
"denne innstillingen er aktivert."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synkroniser Sceneendringer"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Når denne innstillingen er aktivert, alle endringer gjort til scenen i "
"editoren vil bli replikert i det kjørende spillet.\n"
@@ -2982,16 +3008,17 @@ msgstr ""
"nettverksfilsystem."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synkroniser Skriptendringer"
#: editor/editor_node.cpp
#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Når denne innstillingen er aktivert, alle skript som er lagret vil lastes "
"inn på nytt i det kjørende spillet.\n"
@@ -3063,7 +3090,7 @@ msgstr "Hjelp"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Søk"
@@ -3491,9 +3518,11 @@ msgid "Add Key/Value Pair"
msgstr "Legg Til Nøkkel/Verdi Par"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Ingen kjørbar eksport-preset funnet for denne plattformen.\n"
"Vennligst legg til en kjørbar preset i eksportmenyen."
@@ -5389,7 +5418,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Forhåndsvis"
@@ -8167,7 +8196,8 @@ msgid "New Animation"
msgstr "Animasjon"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Hastighet (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10302,6 +10332,7 @@ msgstr ""
"Godotprosjekter.\n"
"Det kan ta en stund."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Prosjektstyring"
@@ -10746,11 +10777,16 @@ msgid "Batch Rename"
msgstr "Endre navn"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Erstatt: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10802,7 +10838,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10864,8 +10900,9 @@ msgid "Reset"
msgstr "Nullstill Zoom"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Gjeldende Versjon:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12922,6 +12959,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13180,6 +13222,18 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke endres."
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "FilSystem"
+
+#, fuzzy
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Ved eksportering eller deploying, den følgende kjørbare filen vil prøve å "
+#~ "koble til IP'en til denne datamaskinen for å bli debugget."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Gjeldende scene ble aldri lagret, vennligst lagre før kjøring."
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 7f111ad901..122782e1b0 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -47,8 +47,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-04 08:58+0000\n"
-"Last-Translator: marnicq van loon <marnicqvanloon@gmail.com>\n"
+"PO-Revision-Date: 2020-08-28 13:09+0000\n"
+"Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
"Language: nl\n"
@@ -56,7 +56,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.2.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -567,6 +567,7 @@ msgid "Seconds"
msgstr "Seconden"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -745,7 +746,7 @@ msgstr "Hoofdlettergevoelig"
msgid "Whole Words"
msgstr "Hele woorden"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Vervangen"
@@ -939,6 +940,11 @@ msgid "Signals"
msgstr "Signalen"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filter tegels"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
"Weet je zeker dat je alle verbindingen naar dit signaal wilt verwijderen?"
@@ -977,7 +983,7 @@ msgid "Recent:"
msgstr "Onlangs:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Zoeken:"
@@ -1160,6 +1166,9 @@ msgstr "Projectoprichters"
msgid "Lead Developer"
msgstr "Hoofdontwikkelaar"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Projectbeheer "
@@ -1181,6 +1190,16 @@ msgid "Gold Sponsors"
msgstr "Gouden Sponsors"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Zilveren Donors"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronzen Donors"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsoren"
@@ -1656,16 +1675,17 @@ msgid "Scene Tree Editing"
msgstr "Scèneboombewerking"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importtabblad"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Knooptabblad"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Bestandssysteem- en Importtablad"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Bestandssysteem"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importtabblad"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1929,7 +1949,7 @@ msgstr "Mappen & Bestanden:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Voorbeeld:"
@@ -2809,24 +2829,28 @@ msgstr "Opstarten met debugging op afstand"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Na het exporteren of opstarten van het programma zal het proberen verbinding "
-"maken met het IP-adres van deze computer zodat het gedebugd kan worden."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Klein uitvoerbaar bestand opstarten met netwerk bestandsserver"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Wanneer deze optie is ingeschakeld, zal export of deploy een minimaal "
"uitvoerbaar bestand creëren.\n"
@@ -2840,9 +2864,10 @@ msgid "Visible Collision Shapes"
msgstr "Toon collision shapes"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Botsingsdetectievormen en raycast knopen (voor 2D en 3D) zullen zichtbaar "
"zijn in het draaiend spel wanneer deze optie aan staat."
@@ -2852,23 +2877,26 @@ msgid "Visible Navigation"
msgstr "Navigatie zichtbaar"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigatie meshes en polygonen zijn zichtbaar in het draaiend spel wanneer "
"deze optie aanstaat."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Scèneveranderingen synchroniseren"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Wanneer deze optie aanstaat, wordt elke verandering gemaakt in de editor "
"toegepast op het draaiend spel.\n"
@@ -2876,15 +2904,17 @@ msgstr ""
"efficiënter met het netwerk bestandssysteem."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Scriptveranderingen synchroniseren"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Wanneer deze optie aanstaat wordt ieder script dat wordt opgeslagen "
"toegepast op het draaiend spel.\n"
@@ -2948,7 +2978,7 @@ msgstr "Help"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Zoeken"
@@ -3368,9 +3398,11 @@ msgid "Add Key/Value Pair"
msgstr "Sleutel/waarde-paar toevoegen"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Geen uitvoerbare export preset gevonden voor dit platform.\n"
"Voeg een uitvoerbare preset toe in het exportmenu."
@@ -5139,7 +5171,7 @@ msgid "Bake Lightmaps"
msgstr "Bak Lichtmappen"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Voorbeeld"
@@ -7361,7 +7393,7 @@ msgstr "Bekijk Omgeving"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Gizmos"
-msgstr "Bekijk Gizmos"
+msgstr "Toon Gizmos"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
@@ -7450,9 +7482,9 @@ msgid ""
msgstr ""
"Klik om te wisselen tussen zichtbaarheidsweergaven.\n"
"\n"
-"Open oog: handvat is zichtbaar.\n"
-"Gesloten oog: handvat is verborgen.\n"
-"Half open oog: handvat is ook zichtbaar door ondoorzichtige oppervlaktes."
+"Open oog: Gizmo is zichtbaar.\n"
+"Gesloten oog: Gizmo is verborgen.\n"
+"Half open oog: Gizmo is ook zichtbaar door ondoorzichtige oppervlaktes."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
@@ -7640,7 +7672,7 @@ msgstr "Post"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Nameless gizmo"
-msgstr "Naamloos apparaat"
+msgstr "Naamloze gizmo"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create Mesh2D"
@@ -7793,7 +7825,8 @@ msgid "New Animation"
msgstr "Niewe animatie"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Snelheid (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9932,6 +9965,7 @@ msgstr ""
"Wil je %s mappen doorzoeken naar bestaande Godot projecten?\n"
"Dit kan een tijdje duren."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projectbeheer"
@@ -10372,11 +10406,18 @@ msgid "Batch Rename"
msgstr "Bulk hernoemen"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Vervangen: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Voorvoegsel"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Achtervoegsel"
#: editor/rename_dialog.cpp
@@ -10424,7 +10465,8 @@ msgid "Per-level Counter"
msgstr "Per niveau teller"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
"Indien ingesteld: herstart de teller voor iedere groep van onderliggende "
"knopen"
@@ -10486,7 +10528,8 @@ msgid "Reset"
msgstr "Resetten"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Fout in reguliere expressie"
#: editor/rename_dialog.cpp
@@ -10596,9 +10639,8 @@ msgid "Make node as Root"
msgstr "Knoop tot wortelknoop maken"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Verwijder knoop \"%s\" en zijn kinderen?"
+msgstr "%d knopen en hun (eventuele) kinderen verwijderen?"
#: editor/scene_tree_dock.cpp
msgid "Delete %d nodes?"
@@ -12567,6 +12609,11 @@ msgstr ""
"GIProbes worden niet ondersteund door het GLES2 grafische stuurprogramma.\n"
"Gebruik in plaats daarvan een BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12873,6 +12920,17 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies."
msgid "Constants cannot be modified."
msgstr "Constanten kunnen niet worden aangepast."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Bestandssysteem- en Importtablad"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Na het exporteren of opstarten van het programma zal het proberen "
+#~ "verbinding maken met het IP-adres van deze computer zodat het gedebugd "
+#~ "kan worden."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "De huidige scène is nooit opgeslagen, sla het op voor het uitvoeren."
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 5859fe6b0a..11fc082ecd 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -506,6 +506,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -684,7 +685,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -873,6 +874,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -910,7 +915,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1084,6 +1089,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1105,6 +1113,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1568,15 +1584,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1839,7 +1855,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2664,22 +2680,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2688,8 +2708,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2698,32 +2718,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2783,7 +2803,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3183,7 +3203,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4907,7 +4928,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7489,7 +7510,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9465,6 +9486,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9895,11 +9917,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9945,7 +9971,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10003,7 +10029,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11932,6 +11958,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index d7ff515b05..7be793ffd2 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -5,8 +5,8 @@
# 8-bit Pixel <dawdejw@gmail.com>, 2016.
# Adam Wolanski <adam.wolanski94@gmail.com>, 2017.
# Adrian Węcławski <weclawskiadrian@gmail.com>, 2016.
-# aelspire <aelspire@gmail.com>, 2017, 2019.
-# Daniel Lewan <vision360.daniel@gmail.com>, 2016-2018.
+# aelspire <aelspire@gmail.com>, 2017, 2019, 2020.
+# Daniel Lewan <vision360.daniel@gmail.com>, 2016-2018, 2020.
# Dariusz Król <rexioweb@gmail.com>, 2018.
# heya10 <igor.gielzak@gmail.com>, 2017.
# holistyczny interlokutor <jakubowesmieci@gmail.com>, 2017.
@@ -16,17 +16,17 @@
# Karol Walasek <coreconviction@gmail.com>, 2016.
# Maksymilian Świąć <maksymilian.swiac@gmail.com>, 2017-2018.
# Mietek Szcześniak <ravaging@go2.pl>, 2016.
-# NeverK <neverkoxu@gmail.com>, 2018, 2019.
-# Rafal Brozio <rafal.brozio@gmail.com>, 2016, 2019.
+# NeverK <neverkoxu@gmail.com>, 2018, 2019, 2020.
+# Rafal Brozio <rafal.brozio@gmail.com>, 2016, 2019, 2020.
# Rafał Ziemniak <synaptykq@gmail.com>, 2017.
# RM <synaptykq@gmail.com>, 2018, 2020.
# Sebastian Krzyszkowiak <dos@dosowisko.net>, 2017.
-# Sebastian Pasich <sebastian.pasich@gmail.com>, 2017, 2019.
+# Sebastian Pasich <sebastian.pasich@gmail.com>, 2017, 2019, 2020.
# siatek papieros <sbigneu@gmail.com>, 2016.
-# Zatherz <zatherz@linux.pl>, 2017.
+# Zatherz <zatherz@linux.pl>, 2017, 2020.
# Tomek <kobewi4e@gmail.com>, 2018, 2019, 2020.
# Wojcieh Er Zet <wojcieh.rzepecki@gmail.com>, 2018.
-# Dariusz Siek <dariuszynski@gmail.com>, 2018, 2019.
+# Dariusz Siek <dariuszynski@gmail.com>, 2018, 2019, 2020.
# Szymon Nowakowski <smnbdg13@gmail.com>, 2019.
# Nie Powiem <blazek10@tlen.pl>, 2019.
# Sebastian Hojka <sibibibi1@gmail.com>, 2019.
@@ -41,12 +41,15 @@
# Jan Ligudziński <jan.ligudzinski@gmail.com>, 2020.
# Adam Jagoda <kontakt@lukasz.xyz>, 2020.
# Filip Glura <mcmr.slendy@gmail.com>, 2020.
+# Roman Skiba <romanskiba0@gmail.com>, 2020.
+# Piotr Grodzki <ziemniakglados@gmail.com>, 2020.
+# Dzejkop <jakubtrad@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-31 03:47+0000\n"
-"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
+"PO-Revision-Date: 2020-09-22 03:23+0000\n"
+"Last-Translator: Zatherz <zatherz@linux.pl>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -55,7 +58,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -244,7 +247,7 @@ msgstr "Ścieżka krzywej Béziera"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr "Ścieżka audio"
+msgstr "Ścieżka dźwiękowa"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
@@ -346,12 +349,12 @@ msgstr "Przytnij"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr "Zawiń"
+msgstr "Zawiń pętlę interpolacji"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Wstaw klucz"
+msgstr "Wprowadź klucz"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
@@ -363,7 +366,7 @@ msgstr "Usuń klucz(e)"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr "Zmień tryb zmiany animacji"
+msgstr "Zmień sposób aktualizacji animacji"
#: editor/animation_track_editor.cpp
msgid "Change Animation Interpolation Mode"
@@ -383,7 +386,7 @@ msgstr "Utworzyć NOWĄ ścieżkę dla %s i wstawić klucz?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "Utworzyć %d NOWYCH ścieżek i wstawić klucze?"
+msgstr "Utworzyć %d NOWYCH ścieżek i dodać klatki kluczowe?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -564,6 +567,7 @@ msgid "Seconds"
msgstr "sekund"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "klatek na sekundę"
@@ -742,7 +746,7 @@ msgstr "Uwzględnij wielkość liter"
msgid "Whole Words"
msgstr "Całe słowa"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Zastąp"
@@ -934,6 +938,11 @@ msgid "Signals"
msgstr "Sygnały"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtruj kafelki"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Na pewno chcesz usunąć wszystkie połączenia z tego sygnału?"
@@ -971,7 +980,7 @@ msgid "Recent:"
msgstr "Ostatnie:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Szukaj:"
@@ -1129,7 +1138,7 @@ msgstr "Zasoby bez jawnych właścicieli:"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Key"
-msgstr "Zmień klucz tablicy"
+msgstr "Zmień klucz słownika"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Value"
@@ -1151,6 +1160,9 @@ msgstr "Założyciele projektu"
msgid "Lead Developer"
msgstr "Deweloper naczelny"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Menedżer projektu "
@@ -1172,6 +1184,14 @@ msgid "Gold Sponsors"
msgstr "Złoci sponsorzy"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Srebrni sponsorzy"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Brązowi sponsorzy"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini-sponsorzy"
@@ -1294,7 +1314,7 @@ msgstr "Przełącz ominięcie efektów w magistrali audio"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr "Wybierz szynę wysyłki audio"
+msgstr "Wybierz przesył magistrali audio"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
@@ -1647,16 +1667,17 @@ msgid "Scene Tree Editing"
msgstr "Edycja drzewa sceny"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Dok importowania"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Dok węzła"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Doki systemu plików i importowania"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "System plików"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Dok importowania"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1919,7 +1940,7 @@ msgstr "Katalogi i pliki:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Podgląd:"
@@ -2794,24 +2815,28 @@ msgstr "Uruchom z użyciem zdalnego debugowania"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Podczas eksportu lub uruchomienia, aplikacja wynikowa spróbuje połączyć się "
-"z adresem IP tego komputera w celu debugowania."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Testuj z sieciowym systemem plików"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Gdy ta opcja jest zaznaczona, eksportowanie utworzy jak najmniejszy plik "
"wykonywalny.\n"
@@ -2824,9 +2849,10 @@ msgid "Visible Collision Shapes"
msgstr "Widoczne kształty kolizji"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Kształty kolizji i promienie raycast (2D i 3D) będą widoczne, jeśli ta opcja "
"będzie zaznaczona."
@@ -2836,23 +2862,26 @@ msgid "Visible Navigation"
msgstr "Widoczna nawigacja"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Kształty i poligony nawigacyjne będą widoczne, jeśli ta opcja będzie "
"zaznaczona."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synchronizuj zmiany w scenie"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kiedy ta opcja jest włączona, wszystkie zmiany na scenie w edytorze będą "
"powtórzone w uruchomionej grze.\n"
@@ -2860,15 +2889,17 @@ msgstr ""
"systemie plików."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synchronizuj zmiany skryptów"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kiedy ta opcja jest włączona, każdy zapisany skrypt będzie przeładowany w "
"uruchomionej grze.\n"
@@ -2932,7 +2963,7 @@ msgstr "Pomoc"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Szukaj"
@@ -3089,7 +3120,7 @@ msgstr "Szablonowy pakiet"
#: editor/editor_node.cpp
msgid "Export Library"
-msgstr "Wyeksportuj biblioteke"
+msgstr "Wyeksportuj bibliotekę"
#: editor/editor_node.cpp
msgid "Merge With Existing"
@@ -3202,7 +3233,7 @@ msgstr "Klatka %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr "Klatki Fizyki %"
+msgstr "Klatka fizyki %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
@@ -3348,9 +3379,11 @@ msgid "Add Key/Value Pair"
msgstr "Dodaj parę klucz/wartość"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Nie znaleziono możliwego do uruchomienia profilu eksportu dla tej "
"platformy.\n"
@@ -3934,11 +3967,11 @@ msgstr "Importuj oddzielnie obiekty i animacje"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials+Animations"
-msgstr "Importuj wraz z Oddzielnymi Materiałami i Animacjami"
+msgstr "Zaimportuj osobno Materiały+Animacje"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials+Animations"
-msgstr "Importuj wraz z Oddzielnymi Obiektami, Materiałami i Animacjami"
+msgstr "Zaimportuj osobno Obiekty+Materiały+Animacje"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes"
@@ -4061,11 +4094,11 @@ msgstr "Kopiuj zasób"
#: editor/inspector_dock.cpp
msgid "Make Built-In"
-msgstr "Skrypt wbudowany"
+msgstr "Stwórz wbudowany"
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
-msgstr "Utwórz unikalne pod-zasoby"
+msgstr "Utwórz unikalne podzasoby"
#: editor/inspector_dock.cpp
msgid "Open in Help"
@@ -4487,7 +4520,7 @@ msgstr "Zmień nazwę animacji"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
-msgstr "Mieszaj następną zmienioną"
+msgstr "Zmieszaj kolejną po zmianach"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
@@ -4527,7 +4560,7 @@ msgstr "Odtwórz zaznaczoną animację od tyłu z aktualnej pozycji. (A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr "Odtwarzaj zaznaczoną animację od końca. (Shift+A)"
+msgstr "Odtwórz zaznaczoną animację od tyłu z końca. (Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
@@ -4591,7 +4624,7 @@ msgstr "Poprzedni"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr "Przyszłość"
+msgstr "Następny"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
@@ -4872,7 +4905,7 @@ msgstr "Węzeł Skalowania Czasu"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "TimeSeek Node"
-msgstr "Węzeł TimeSeek"
+msgstr "Węzeł Przewijania w Czasie"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Transition Node"
@@ -4949,8 +4982,7 @@ msgstr "Przekroczenie czasu."
#: 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ł "
-"niepoprawnie pobrany."
+"Zła suma kontrolna pobranego pliku. Zakładamy, że ktoś przy nim majstrował."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
@@ -5050,7 +5082,7 @@ msgstr "Wszystko"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr "Brak rezultatów dla \"%s\"."
+msgstr "Brak wyników dla \"%s\"."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Import..."
@@ -5122,7 +5154,7 @@ msgid "Bake Lightmaps"
msgstr "Stwórz Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Podgląd"
@@ -5408,7 +5440,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
-msgstr "Alt+PPM: Lista obiektów pod spodem"
+msgstr "Alt+PPM: Wybór listy głębi"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7771,7 +7803,8 @@ msgid "New Animation"
msgstr "Nowa animacja"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Prędkość (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9539,7 +9572,7 @@ msgstr "Plik paczki"
#: editor/project_export.cpp
msgid "Features"
-msgstr "Funkcjonalności"
+msgstr "Funkcje"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9898,6 +9931,7 @@ msgstr ""
"projektów Godota?\n"
"To może chwilę zająć."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Menedżer projektów"
@@ -10338,11 +10372,18 @@ msgid "Batch Rename"
msgstr "Grupowa zmiana nazwy"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Zastąp: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Przedrostek"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Przyrostek"
#: editor/rename_dialog.cpp
@@ -10390,7 +10431,8 @@ msgid "Per-level Counter"
msgstr "Oddzielny licznik na poziom"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Gdy ustawione, licznik restartuje dla każdej grupy węzłów potomnych"
#: editor/rename_dialog.cpp
@@ -10450,7 +10492,8 @@ msgid "Reset"
msgstr "Resetuj"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Błąd wyrażenia regularnego"
#: editor/rename_dialog.cpp
@@ -12538,6 +12581,11 @@ msgstr ""
"GIProbes nie są obsługiwane przez sterownik wideo GLES2.\n"
"Zamiast tego użyj BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight z kątem szerszym niż 90 stopni nie może rzucać cieni."
@@ -12841,6 +12889,16 @@ 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 "FileSystem and Import Docks"
+#~ msgstr "Doki systemu plików i importowania"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Podczas eksportu lub uruchomienia, aplikacja wynikowa spróbuje połączyć "
+#~ "się z adresem IP tego komputera w celu debugowania."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Aktualna scena nie została zapisana, proszę zapisać scenę przed "
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index bf2d3ef0ad..d1b82cffe6 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -536,6 +536,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -716,7 +717,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -914,6 +915,11 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Paste yer Node"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -953,7 +959,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1127,6 +1133,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1148,6 +1157,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1623,16 +1640,17 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr ""
-
-#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Node Dock"
msgstr "Find ye Node Type"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Rename Variable"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1907,7 +1925,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2750,22 +2768,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2774,8 +2796,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2784,32 +2806,33 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
-msgstr ""
+#, fuzzy
+msgid "Synchronize Script Changes"
+msgstr "Change"
#: 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2872,7 +2895,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3281,7 +3304,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5072,7 +5096,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7734,7 +7758,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9789,6 +9813,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10228,11 +10253,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10280,7 +10309,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10339,7 +10368,7 @@ msgstr ""
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "Swap yer Expression"
#: editor/rename_dialog.cpp
@@ -12365,6 +12394,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt.po
index b9d6c82ff0..6b6a15dda7 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt.po
@@ -1,4 +1,4 @@
-# Portuguese (Portugal) translation of the Godot Engine editor
+# Portuguese translation of the Godot Engine editor
# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
@@ -13,23 +13,23 @@
# Rueben Stevens <supercell03@gmail.com>, 2017.
# SARDON <fabio3_Santos@hotmail.com>, 2017.
# Vinicius Gonçalves <viniciusgoncalves21@gmail.com>, 2017.
-# ssantos <ssantos@web.de>, 2018, 2019.
+# ssantos <ssantos@web.de>, 2018, 2019, 2020.
# Gonçalo Dinis Guerreiro João <goncalojoao205@gmail.com>, 2019.
# Manuela Silva <mmsrs@sky.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-31 03:47+0000\n"
-"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
-"Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/"
-"godot-engine/godot/pt_PT/>\n"
-"Language: pt_PT\n"
+"PO-Revision-Date: 2020-09-24 12:43+0000\n"
+"Last-Translator: ssantos <ssantos@web.de>\n"
+"Language-Team: Portuguese <https://hosted.weblate.org/projects/"
+"godot-engine/godot/pt/>\n"
+"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -540,6 +540,7 @@ msgid "Seconds"
msgstr "Segundos"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -718,7 +719,7 @@ msgstr "Caso de Compatibilidade"
msgid "Whole Words"
msgstr "Palavras inteiras"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Substituir"
@@ -836,7 +837,7 @@ msgstr "Deferido"
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
msgstr ""
-"Retarda o sinal, armazena-o numa fila e só ativando-o em tempo de "
+"Retarda o sinal, armazena-o numa fila e só a ativar-o em tempo de "
"inatividade."
#: editor/connections_dialog.cpp
@@ -911,6 +912,11 @@ msgid "Signals"
msgstr "Sinais"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrar Tiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Deseja remover todas as conexões deste sinal?"
@@ -948,7 +954,7 @@ msgid "Recent:"
msgstr "Recente:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Procurar:"
@@ -1037,7 +1043,7 @@ msgstr "Proprietários de:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Remover arquivos selecionados do Projeto? (Sem desfazer)"
+msgstr "Remover ficheiros selecionados do Projeto? (Sem desfazer)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1045,7 +1051,7 @@ msgid ""
"work.\n"
"Remove them anyway? (no undo)"
msgstr ""
-"Os arquivos a serem removidos são necessários para que outros recursos "
+"Os ficheiros a serem removidos são necessários para que outros recursos "
"funcionem.\n"
"Remover mesmo assim? (sem anular)"
@@ -1129,6 +1135,9 @@ msgstr "Fundadores do Projeto"
msgid "Lead Developer"
msgstr "Desenvolvedor-chefe"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Gestor de Projeto "
@@ -1143,11 +1152,19 @@ msgstr "Autores"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr "Patrocinadores Platinum"
+msgstr "Patrocinadores Platina"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr "Patrocinadores Gold"
+msgstr "Patrocinadores Ouro"
+
+#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Patrocinadores Prata"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Patrocinadores Bronze"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -1403,11 +1420,11 @@ msgstr "Guardar este Modelo de Barramento para um ficheiro."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
-msgstr "Carregar Padrão"
+msgstr "Carregar Predefinição"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr "Carregar o Modelo padrão de barramento."
+msgstr "Carregar o Modelo predefinido de barramento."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
@@ -1505,7 +1522,7 @@ msgstr "A atualizar Cena"
#: editor/editor_data.cpp
msgid "Storing local changes..."
-msgstr "Armazenando alterações locais..."
+msgstr "A armazenar alterações locais..."
#: editor/editor_data.cpp
msgid "Updating scene..."
@@ -1551,7 +1568,7 @@ msgstr "Escolha"
#: editor/editor_export.cpp
msgid "Storing File:"
-msgstr "Arquivo de Armazenamento:"
+msgstr "Armazenar o Ficheiro:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
@@ -1627,16 +1644,17 @@ msgid "Scene Tree Editing"
msgstr "Edição da Árvore de Cena"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importar Doca"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Doca de Nó"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Sistema de Ficheiros e Docas de Importação"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistema de Ficheiros"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importar Doca"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1899,7 +1917,7 @@ msgstr "Diretorias e Ficheiros:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Pré-visualização:"
@@ -1962,7 +1980,7 @@ msgstr "Sobrepõe:"
#: editor/editor_help.cpp
msgid "default:"
-msgstr "Padrão:"
+msgstr "predefinição:"
#: editor/editor_help.cpp
msgid "Methods"
@@ -1994,7 +2012,7 @@ msgid ""
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
"Atualmente não existe descrição para esta Propriedade. Por favor ajude-nos "
-"[color=$color][url=$url]contribuindo com uma[/url][/color]!"
+"[color=$color][url=$url]a contribuir com uma[/url][/color]!"
#: editor/editor_help.cpp
msgid "Method Descriptions"
@@ -2006,7 +2024,7 @@ msgid ""
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
"Atualmente não existe descrição para este Método. Por favor ajude-nos [color="
-"$color][url=$url]contribuindo com uma[/url][/color]!"
+"$color][url=$url]a contribuir com uma[/url][/color]!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -2220,11 +2238,11 @@ msgstr "A guardar Cena"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr "Analizando"
+msgstr "A analizar"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr "Criando Miniatura"
+msgstr "A criar miniatura"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
@@ -2273,7 +2291,7 @@ msgstr "Erro ao tentar guardar o Modelo!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr "O Modelo do Editor padrão foi substituído."
+msgstr "O modelo do editor predefinido foi substituído."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2281,7 +2299,7 @@ msgstr "Nome do Modelo não encontrado!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
-msgstr "Modelo padrão restaurado para as configurações base."
+msgstr "Modelo predefinido restaurado para as configurações base."
#: editor/editor_node.cpp
msgid ""
@@ -2289,7 +2307,7 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
-"Este recurso pertence a uma cena que foi importado, não sendo editável.\n"
+"Este recurso pertence a uma cena que foi importado, sem ser editável.\n"
"Por favor, leia a documentação relevante sobre importação de cenas, para um "
"melhor entendimento deste fluxo de trabalho."
@@ -2318,7 +2336,7 @@ msgid ""
msgstr ""
"Esta cena foi importada, portanto, as alterações à mesma não serão "
"mantidas.\n"
-"Instanciando-a ou herdando-a vai permitir efetuar alterações à mesma.\n"
+"Instanciar-a ou herdar-a vai permitir efetuar alterações à mesma.\n"
"Por favor, leia a documentação relevante sobre importação de cenas, para um "
"melhor entendimento do fluxo de trabalho."
@@ -2521,7 +2539,7 @@ msgid ""
"Scene '%s' was automatically imported, so it can't be modified.\n"
"To make changes to it, a new inherited scene can be created."
msgstr ""
-"Cena '%s' foi importada automaticamente, não podendo ser alterada.\n"
+"Cena '%s' foi importada automaticamente, sem poder ser alterada.\n"
"Para fazer alterações, pode ser criada uma nova cena herdada."
#: editor/editor_node.cpp
@@ -2547,8 +2565,8 @@ msgid ""
"category."
msgstr ""
"Não foi definida nenhuma cena principal. Selecionar uma?\n"
-"Poderá alterá-la depois nas \"Definições do Projeto\", na categoria "
-"'aplicação'."
+"Poderá alterá-la depois nas \"Configurações do Projeto\", na categoria "
+"'Application'."
#: editor/editor_node.cpp
msgid ""
@@ -2557,8 +2575,7 @@ msgid ""
"category."
msgstr ""
"A cena selecionada '%s' não existe, selecionar uma válida?\n"
-"Poderá alterá-la depois em \"Configurações de Projeto\", na categoria "
-"'aplicação'."
+"Poderá alterá-la depois em \"application\", na categoria 'Application'."
#: editor/editor_node.cpp
msgid ""
@@ -2568,8 +2585,8 @@ msgid ""
msgstr ""
"A cena selecionada '%s' não é um ficheiro de cena, selecione um ficheiro "
"válido?\n"
-"Poderá alterá-la depois em \"Configurações de Projeto\", na categoria "
-"'aplicação'."
+"Poderá alterá-la depois em \"Configurações do Projeto\", na categoria "
+"'Application."
#: editor/editor_node.cpp
msgid "Save Layout"
@@ -2582,7 +2599,7 @@ msgstr "Apagar Modelo"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr "Padrão"
+msgstr "Predefinição"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
@@ -2730,7 +2747,7 @@ msgstr "Projeto"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr "Configurações de Projeto..."
+msgstr "Configurações do Projeto..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -2779,24 +2796,28 @@ msgstr "Implementar com Depuração Remota"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Ao exportar ou distribuir, o executável vai tentar ligar-se ao IP deste "
-"computador para depuração."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Pequena distribuição com Network FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Quando esta opção é ativada, exportação ou distribuição criará um executável "
"mínimo.\n"
@@ -2809,9 +2830,10 @@ msgid "Visible Collision Shapes"
msgstr "Formas de Colisão Visíveis"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Com esta opção ativa, formas de colisão e nós raycast (para 2D e 3D) serão "
"visíveis no jogo em execução."
@@ -2821,42 +2843,47 @@ msgid "Visible Navigation"
msgstr "Navegação Visível"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Com esta opção ativa, Meshes e Polígonos serão visíveis no jogo em execução."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizar Alterações de Cena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Com esta opção ativa, alterações da cena no editor serão replicadas no jogo "
"em execução.\n"
-"Quando usada num dispositivo remoto, é mais eficiente com um sistema de "
+"Quando usada num aparelho remoto, é mais eficiente com um sistema de "
"ficheiros em rede."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizar Alterações de Script"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Com esta opção ativa, qualquer Script guardado será recarregado no jogo em "
"execução.\n"
-"Quando usada num dispositivo remoto, é mais eficiente com um Sistema de "
+"Quando usada num aparelho remoto, é mais eficiente com um Sistema de "
"Ficheiros em rede."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2917,7 +2944,7 @@ msgstr "Ajuda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Procurar"
@@ -3048,7 +3075,7 @@ msgstr ""
"O projeto será preparado para compilações personalizadas Android com a "
"instalação do modelo fonte em \"res://android/build\".\n"
"Poderá depois aplicar modificações e compilar o seu APK personalizado a "
-"exportar (com adição de módulos, alterando AndroidManifest.xml, etc.).\n"
+"exportar (com adição de módulos, a alterar AndroidManifest.xml, etc.).\n"
"Repare que de forma a criar compilações personalizadas em vez de usar APKs "
"pré-compilados, a opção \"Usar Compilação Personalizada\" deve ser ativada "
"na predefinição da exportação Android."
@@ -3334,9 +3361,11 @@ msgid "Add Key/Value Pair"
msgstr "Adicionar Par Chave/Valor"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Não foi encontrado um executável de exportação para esta plataforma.\n"
"Adicione um executável pré-definido no menu de exportação."
@@ -3464,8 +3493,9 @@ msgid ""
"No download links found for this version. Direct download is only available "
"for official releases."
msgstr ""
-"Não foram encontrados ligações para download para esta versão. Download "
-"direto está apenas disponível para os lançamentos oficiais."
+"Não foram encontrados ligações para descarregar para esta versão. "
+"Descarregamentos diretos estão disponíveis apenas para os lançamentos "
+"oficiais."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3509,7 +3539,7 @@ msgid ""
"The problematic templates archives can be found at '%s'."
msgstr ""
"Falhou a instalação de Modelos.\n"
-"Os ficheiros problemáticos podem ser encontrados em '%s'."
+"Os ficheiros problemáticos encontram-se em '%s'."
#: editor/export_template_manager.cpp
msgid "Error requesting URL:"
@@ -3981,11 +4011,11 @@ msgstr "%d Ficheiros"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
-msgstr "Definir como Padrão para '%s'"
+msgstr "Definir como Predefinição para '%s'"
#: editor/import_dock.cpp
msgid "Clear Default for '%s'"
-msgstr "Limpar Padrão para '%s'"
+msgstr "Limpar Predefinição para '%s'"
#: editor/import_dock.cpp
msgid "Import As:"
@@ -4011,7 +4041,7 @@ msgstr "Alterar o tipo de um ficheiro importado requer reiniciar o editor."
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
-"AVISO: Existem Ativos que usam este recurso, podendo não ser carregados "
+"AVISO: Existem Ativos que usam este recurso, poderem não ser carregados "
"corretamente."
#: editor/inspector_dock.cpp
@@ -4304,7 +4334,7 @@ msgstr "Alternar Triângulos Auto"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
-msgstr "Criar triângulos ligando pontos."
+msgstr "Criar triângulos a ligar pontos."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
@@ -4381,13 +4411,13 @@ msgstr "Alterar Filtro"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
msgstr ""
-"Reprodutor de animação não definido, sendo incapaz de recolher nome das "
+"Reprodutor de animação não definido, a ser incapaz de recolher nome das "
"faixas."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
msgstr ""
-"Caminho do reprodutor é inválido, sendo incapaz de recolher nome das faixas."
+"Caminho do reprodutor é inválido, a ser incapaz de recolher nome das faixas."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4395,7 +4425,7 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
-"Reprodutor de animação não tem um caminha de nó raiz válido, sendo incapaz "
+"Reprodutor de animação não tem um caminha de nó raiz válido, a ser incapaz "
"de recolher nome das faixas."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -5101,7 +5131,7 @@ msgid "Bake Lightmaps"
msgstr "Consolidar Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Pré-visualização"
@@ -5598,8 +5628,8 @@ msgid ""
msgstr ""
"Insere chaves automaticamente quando objetos são movidos, rodados ou "
"redimensionados (baseado na máscara).\n"
-"Chaves apenas são adicionadas a pistas existentes, não sendo criadas novas "
-"pistas.\n"
+"Chaves apenas são adicionadas a pistas existentes, nenhumas pistas serão "
+"criadas.\n"
"Chaves têm de ser inseridas manualmente na primeira vez."
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5658,7 +5688,7 @@ msgstr "Erro a instanciar cena de %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Default Type"
-msgstr "Mudar Tipo Padrão"
+msgstr "Mudar Predefinição de Tipo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -6396,7 +6426,7 @@ msgstr "Criar mapa UV"
msgid ""
"Polygon 2D has internal vertices, so it can no longer be edited in the "
"viewport."
-msgstr "Polygon 2D tem vértices internos, não podendo ser editado no viewport."
+msgstr "Polygon 2D tem vértices internos, não poder ser editado no viewport."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create Polygon & UV"
@@ -6489,7 +6519,7 @@ msgstr "Escalar Polígono"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create a custom polygon. Enables custom polygon rendering."
msgstr ""
-"Crie um polígono personalizado. Habilita a renderização de polígonos "
+"Crie um polígono personalizado. Ativa a renderização de polígonos "
"personalizados."
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -7742,7 +7772,8 @@ msgid "New Animation"
msgstr "Nova Animação"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocidade (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8577,7 +8608,7 @@ msgstr "Definir Nome do Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Input Default Port"
-msgstr "Definir Porta de Entrada Padrão"
+msgstr "Definir Porta de Entrada Predefinida"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node to Visual Shader"
@@ -8997,7 +9028,7 @@ msgstr ""
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"usando polinomiais Hermite."
+"a usar polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9087,9 +9118,9 @@ msgstr ""
"\n"
"OuterProduct trata o primeiro parâmetro 'c' como um vetor coluna (matriz com "
"uma coluna) e o segundo parâmetro 'r' como um vetor linha (matriz com uma "
-"linha) e faz uma multiplicação matricial algébrica linear 'c * r', "
-"resultando uma matriz cujo número de linhas é o número de componentes em 'c' "
-"e cujo número de colunas é o número de componentes de 'r'."
+"linha) e faz uma multiplicação matricial algébrica linear 'c * r', a "
+"resultar uma matriz cujo número de linhas é o número de componentes em 'c' e "
+"cujo número de colunas é o número de componentes de 'r'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
@@ -9177,7 +9208,7 @@ msgstr "Interpolação linear entre dois vetores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors using scalar."
-msgstr "Interpolação linear entre dois vetores usando um escalar."
+msgstr "Interpolação linear entre dois vetores a usar um escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
@@ -9215,7 +9246,7 @@ msgstr ""
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"usando polinomiais Hermite."
+"a usar polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9229,7 +9260,7 @@ msgstr ""
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"usando polinomiais Hermite."
+"a usar polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9305,8 +9336,8 @@ msgid ""
"it later in the Expressions. You can also declare varyings, uniforms and "
"constants."
msgstr ""
-"Expressão personalizada em Linguagem Godot Shader, colocada sobre o shader "
-"resultante. Pode colocar várias definições de função e chamá-las depois nas "
+"Expressão personalizada em Linguagem Godot Shader, posta sobre o shader "
+"resultante. Pode pôr várias definições de função e chamá-las depois nas "
"Expressões. Também pode declarar variantes, uniformes e constantes."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9321,14 +9352,14 @@ msgstr "(Apenas modo Fragment/Light) Função derivada vetorial."
msgid ""
"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
"differencing."
-msgstr "(Apenas modo Fragment/Light) Derivada em 'x' usando derivação local."
+msgstr "(Apenas modo Fragment/Light) Derivada em 'x' a usar derivação local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
"differencing."
msgstr ""
-"(Apenas modo Fragment/Light) (Escalar) Derivada em 'x' usando derivação "
+"(Apenas modo Fragment/Light) (Escalar) Derivada em 'x' a usar derivação "
"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9336,14 +9367,14 @@ msgid ""
"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
"differencing."
msgstr ""
-"(Apenas modo Fragment/Light) (Vetor) Derivada em 'y' usando derivação local."
+"(Apenas modo Fragment/Light) (Vetor) Derivada em 'y' a usar derivação local."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
"differencing."
msgstr ""
-"(Apenas modo Fragment/Light) (Escalar) Derivada em 'y' usando derivação "
+"(Apenas modo Fragment/Light) (Escalar) Derivada em 'y' a usar derivação "
"local."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9808,8 +9839,8 @@ msgid ""
"the \"Application\" category."
msgstr ""
"Não consigo executar o projeto: cena principal não definida.\n"
-"Edite o projeto e defina a cena principal em Definições do Projeto dentro da "
-"categoria \"Aplicação\"."
+"Edite o projeto e defina a cena principal em Configurações do Projeto dentro "
+"da categoria \"Application\"."
#: editor/project_manager.cpp
msgid ""
@@ -9864,6 +9895,7 @@ msgstr ""
"Pretende pesquisar %s pastas por projetos Godot existentes?\n"
"Pode demorar um pouco."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestor de Projetos"
@@ -9965,11 +9997,11 @@ msgstr "Adicionar evento ação de entrada"
#: editor/project_settings_editor.cpp
msgid "All Devices"
-msgstr "Todos os Dispositivos"
+msgstr "Todos os Aparelhos"
#: editor/project_settings_editor.cpp
msgid "Device"
-msgstr "Dispositivo"
+msgstr "Aparelho"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
@@ -10149,7 +10181,7 @@ msgstr "Modo filtro de localização alterado"
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
-msgstr "Definições do Projeto (project.godot)"
+msgstr "Configurações do Projeto (project.godot)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
@@ -10181,7 +10213,7 @@ msgstr "Zona morta"
#: editor/project_settings_editor.cpp
msgid "Device:"
-msgstr "Dispositivo:"
+msgstr "Aparelho:"
#: editor/project_settings_editor.cpp
msgid "Index:"
@@ -10304,11 +10336,18 @@ msgid "Batch Rename"
msgstr "Renomear em massa"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Substituir: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefixo"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufixo"
#: editor/rename_dialog.cpp
@@ -10356,7 +10395,8 @@ msgid "Per-level Counter"
msgstr "Contador por nível"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Se definido o contador reinicia para cada grupo de nós filhos"
#: editor/rename_dialog.cpp
@@ -10416,7 +10456,8 @@ msgid "Reset"
msgstr "Repor"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Erro em Expressão Regular"
#: editor/rename_dialog.cpp
@@ -10425,11 +10466,11 @@ msgstr "No carácter %s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
-msgstr "Recolocar Nó"
+msgstr "Repôr Nó"
#: editor/reparent_dialog.cpp
msgid "Reparent Location (Select new Parent):"
-msgstr "Recolocar localização (selecionar novo Parente):"
+msgstr "Repôr localização (selecionar novo Parente):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
@@ -10437,7 +10478,7 @@ msgstr "Manter transformação global"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
-msgstr "Recolocar"
+msgstr "Repôr"
#: editor/run_settings_dialog.cpp
msgid "Run Mode:"
@@ -10562,7 +10603,7 @@ msgid ""
"reverted to their default."
msgstr ""
"Desativar \"editable_instance\" irá reverter todas as propriedades do nó "
-"para os seus valores padrão."
+"para os seus valores predefinição."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10570,7 +10611,8 @@ msgid ""
"cause all properties of the node to be reverted to their default."
msgstr ""
"Ativar \"Carregar como Espaço Reservado\" vai desativar \"Filhos Editáveis\" "
-"e fazer com que todas as propriedades do nó revertam para valores padrão."
+"e fazer com que todas as propriedades do nó revertam para valores "
+"predefinidos."
#: editor/scene_tree_dock.cpp
msgid "Make Local"
@@ -10680,7 +10722,7 @@ msgstr "Mudar tipo"
#: editor/scene_tree_dock.cpp
msgid "Reparent to New Node"
-msgstr "Recolocar o Novo Nó"
+msgstr "Repôr o Novo Nó"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
@@ -11539,7 +11581,7 @@ msgstr "Mudar nome do argumento"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Default Value"
-msgstr "Definir Valor Padrão da Variável"
+msgstr "Definir Valor Predefinido da Variável"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Type"
@@ -11881,7 +11923,7 @@ msgstr "VariableSet não encontrado no script: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
-"Nó personalizado não tem método _step(), não podendo processar um gráfico."
+"Nó personalizado não tem método _step(), sem poder processar um gráfico."
#: modules/visual_script/visual_script_nodes.cpp
msgid ""
@@ -11931,7 +11973,7 @@ msgstr "O pacote deve ter pelo menos um separador '.'."
#: platform/android/export/export.cpp
msgid "Select device from the list"
-msgstr "Selecionar dispositivo da lista"
+msgstr "Selecionar aparelho da lista"
#: platform/android/export/export.cpp
msgid "ADB executable not configured in the Editor Settings."
@@ -12083,7 +12125,7 @@ msgstr "Executar no Navegador"
#: platform/javascript/export/export.cpp
msgid "Run exported HTML in the system's default browser."
-msgstr "Executar HTML exportado no Navegador padrão do sistema."
+msgstr "Executar HTML exportado no navegador predefinido do sistema."
#: platform/javascript/export/export.cpp
msgid "Could not write file:"
@@ -12107,7 +12149,7 @@ msgstr "Não consigo ler ficheiro de imagem do ecrã de inicialização:"
#: platform/javascript/export/export.cpp
msgid "Using default boot splash image."
-msgstr "A usar imagem padrão de inicialização."
+msgstr "A usar imagem de inicialização predefinida."
#: platform/uwp/export/export.cpp
msgid "Invalid package short name."
@@ -12190,7 +12232,7 @@ msgid ""
"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
"define its shape."
msgstr ""
-"Este nó não tem forma, não podendo colidir ou interagir com outros objetos.\n"
+"Este nó não tem forma, em poder colidir ou interagir com outros objetos.\n"
"Considere adicionar nós CollisionShape2D ou CollisionPolygon2D como filhos "
"para definir a sua forma."
@@ -12299,7 +12341,7 @@ msgid ""
"A material to process the particles is not assigned, so no behavior is "
"imprinted."
msgstr ""
-"Não foi atribuído um Material para processar as partículas, não possuindo um "
+"Não foi atribuído um Material para processar as partículas, sem possuir um "
"comportamento."
#: scene/2d/particles_2d.cpp
@@ -12333,7 +12375,7 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
-msgstr "Esta corrente de Bone2D deve terminar em um nó Skeleton2D."
+msgstr "Esta corrente de Bone2D deve terminar num nó Skeleton2D."
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
@@ -12424,7 +12466,7 @@ msgid ""
"Consider adding a CollisionShape or CollisionPolygon as a child to define "
"its shape."
msgstr ""
-"Este nó não tem forma, não podendo colidir ou interagir com outros objetos.\n"
+"Este nó não tem forma, sem poder colidir ou interagir com outros objetos.\n"
"Considere adicionar nós CollisionShape ou CollisionPolygon como filhos para "
"definir a sua forma."
@@ -12497,6 +12539,11 @@ msgstr ""
"Sondas GI não são suportadas pelo driver vídeo GLES2.\n"
"Em vez disso, use um BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "Uma SpotLight com ângulo superior a 90 graus não cria sombras."
@@ -12548,8 +12595,8 @@ msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
msgstr ""
-"ROTATION_ORIENTED de PathFollow requer \"Up Vector\" habilitado no recurso "
-"de Curva do Caminho do seu pai."
+"ROTATION_ORIENTED de PathFollow requer \"Up Vector\" ativado no recurso de "
+"Curva do Caminho do seu pai."
#: scene/3d/physics_body.cpp
msgid ""
@@ -12649,7 +12696,7 @@ msgstr "Não foi definida uma raiz AnimationNode para o gráfico."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
msgstr ""
-"Caminho para um nó AnimationPlayer contendo animações não está definido."
+"Caminho para um nó AnimationPlayer a conter animações não está definido."
#: scene/animation/animation_tree.cpp
msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
@@ -12754,7 +12801,7 @@ msgid ""
"Default Environment as specified in Project Settings (Rendering -> "
"Environment -> Default Environment) could not be loaded."
msgstr ""
-"Ambiente Padrão especificado em Configuração do Projeto (Rendering -> "
+"Ambiente predefinido especificado em Configurações do Projeto (Rendering -> "
"Environment -> Default Environment) não pode ser carregado."
#: scene/main/viewport.cpp
@@ -12801,6 +12848,16 @@ 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 "FileSystem and Import Docks"
+#~ msgstr "Sistema de Ficheiros e Docas de Importação"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Ao exportar ou distribuir, o executável vai tentar ligar-se ao IP deste "
+#~ "computador para depuração."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "A cena atual nunca foi guardada, por favor guarde-a antes de executar."
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 6c035decd5..29b0350e10 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -99,12 +99,13 @@
# GUILHERME SOUZA REIS DE MELO LOPES <guilhermesrml@unipam.edu.br>, 2020.
# Gabriela Araújo <Gabirin@outlook.com.br>, 2020.
# Jairo Tuboi <tuboi.jairo@gmail.com>, 2020.
+# Felipe Fetter <felipetfetter@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
-"Last-Translator: Jairo Tuboi <tuboi.jairo@gmail.com>\n"
+"PO-Revision-Date: 2020-09-12 00:46+0000\n"
+"Last-Translator: Felipe Fetter <felipetfetter@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -112,7 +113,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -621,6 +622,7 @@ msgid "Seconds"
msgstr "Segundos"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -799,7 +801,7 @@ msgstr "Caso de correspondência"
msgid "Whole Words"
msgstr "Palavras Inteiras"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Substituir"
@@ -991,6 +993,11 @@ msgid "Signals"
msgstr "Sinais"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtros do tile"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Tem certeza que quer remover todas conexões desse sinal?"
@@ -1028,7 +1035,7 @@ msgid "Recent:"
msgstr "Recente:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Pesquisar:"
@@ -1209,9 +1216,12 @@ msgstr "Fundadores do Projeto"
msgid "Lead Developer"
msgstr "Desenvolvedor-chefe"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Gerenciador de Projetos "
+msgstr "Gerente do Projeto "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1230,6 +1240,14 @@ msgid "Gold Sponsors"
msgstr "Patrocinadores Ouro"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Patrocinadores Prata"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Patrocinadores Bronze"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Patrocinadores Mini"
@@ -1705,16 +1723,17 @@ msgid "Scene Tree Editing"
msgstr "Edição da Árvore de Cena"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importar Dock"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Painel de Nós"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Sistema de Arquivos e Importar Docks"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Arquivos"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importar Dock"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1977,7 +1996,7 @@ msgstr "Diretórios & Arquivos:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Previsualização:"
@@ -2859,24 +2878,28 @@ msgstr "Distribuir com Depuragem Remota"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Quando exportando ou instalando, o programa resultante tentará conectar ao "
-"IP deste computador para poder ser depurado."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Pequena DIstribuição com Sistema de Arquivos de Rede"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Quando esta opção está habilitada, a exportação ou instalação produzirá um "
"executável mínimo.\n"
@@ -2889,9 +2912,10 @@ msgid "Visible Collision Shapes"
msgstr "Formas de Colisão Visíveis"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Formas de colisão e nós do tipo RayCast (2D e 3D) serão visíveis durante a "
"execução do jogo caso esta opção esteja habilitada."
@@ -2901,23 +2925,26 @@ msgid "Visible Navigation"
msgstr "Navegação Visível"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Malhas e polígonos de navegação serão visíveis no jogo em execução se esta "
"opção estiver ligada."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizar Mudanças de Cena"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Quando essa opção está ativa, quaisquer alterações feitas à cena no editor "
"serão replicadas no jogo em execução.\n"
@@ -2925,15 +2952,17 @@ msgstr ""
"sistema de arquivos via rede."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizar Mudanças de Script"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Quando essa opção está ativa, qualquer script que é salvo será recarregado "
"no jogo em execução.\n"
@@ -2997,7 +3026,7 @@ msgstr "Ajuda"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Pesquisar"
@@ -3416,9 +3445,11 @@ msgid "Add Key/Value Pair"
msgstr "Adicionar Par de Chave/Valor"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Não foi encontrado uma definição de exportação executável para esta "
"plataforma.\n"
@@ -5193,7 +5224,7 @@ msgid "Bake Lightmaps"
msgstr "Preparar Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Visualização"
@@ -7841,7 +7872,8 @@ msgid "New Animation"
msgstr "Nova animação"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Velocidade (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9966,6 +9998,7 @@ msgstr ""
"existentes?\n"
"Isso pode levar algum tempo."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gerenciador de Projetos"
@@ -10406,11 +10439,18 @@ msgid "Batch Rename"
msgstr "Renomear em lote"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Substituir: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Prefixo"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Sufixo"
#: editor/rename_dialog.cpp
@@ -10458,7 +10498,8 @@ msgid "Per-level Counter"
msgstr "Contador de nível"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Se definido, o contador será reiniciado para cada grupo de nós filhos"
#: editor/rename_dialog.cpp
@@ -10518,7 +10559,8 @@ msgid "Reset"
msgstr "Recompor"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Erro de Expressão Regular"
#: editor/rename_dialog.cpp
@@ -12602,6 +12644,11 @@ msgstr ""
"GIProbes não são suportados pelo driver de vídeo GLES2.\n"
"Use um BakedLightmap em vez disso."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "Um SpotLight com um ângulo maior que 90 graus não pode criar sombras."
@@ -12909,6 +12956,16 @@ 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 "FileSystem and Import Docks"
+#~ msgstr "Sistema de Arquivos e Importar Docks"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Quando exportando ou instalando, o programa resultante tentará conectar "
+#~ "ao IP deste computador para poder ser depurado."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "A cena atual nunca foi salva. Por favor salve antes de rodá-la."
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index 29487392f8..1549250858 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -538,6 +538,7 @@ msgid "Seconds"
msgstr "Secunde"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS(cadre pe secundă)"
@@ -716,7 +717,7 @@ msgstr "Potrivește Caz-ul"
msgid "Whole Words"
msgstr "Cuvinte Complete"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Înlocuiți"
@@ -908,6 +909,11 @@ msgid "Signals"
msgstr "Semnale"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrare Tiles"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Ești sigur că vrei să ștergi toate conexiunile de la acest semnal?"
@@ -945,7 +951,7 @@ msgid "Recent:"
msgstr "Recent:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Cautați:"
@@ -1126,6 +1132,9 @@ msgstr "Fondatorii Proiectului"
msgid "Lead Developer"
msgstr "Dezvoltator Principal"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Manager de Proiect "
@@ -1147,6 +1156,16 @@ msgid "Gold Sponsors"
msgstr "Sponsori Aur"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Donatori de Argint"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Donatori de Bronz"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsori"
@@ -1627,16 +1646,17 @@ msgid "Scene Tree Editing"
msgstr "Editează Arborele Scenei"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importă Bară"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Nod Bară"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Sistemul De Fișiere și încărcare Bare"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Sistemul De Fișiere"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importă Bară"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1901,7 +1921,7 @@ msgstr "Directoare și Fişiere:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Previzualizați:"
@@ -2787,24 +2807,28 @@ msgstr "Lansează cu Depanare la Distanță"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Când exporți sau lansezi, executabilul rezultat va încerca să se conecteze "
-"la IP-ul acestui computer pentru a putea fi depanat."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Mini Lansare cu Rețea FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Când această opțiune este activată, exportarea sau lansarea va produce un "
"executabil minimal.\n"
@@ -2817,9 +2841,10 @@ msgid "Visible Collision Shapes"
msgstr "Forme de Coliziune Vizibile"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Formele de coliziune si nodurile raycast (pentru 2D și 3D) vor fi vizibile "
"când jocul rulează dacă această opțiune este activată."
@@ -2829,23 +2854,26 @@ msgid "Visible Navigation"
msgstr "Navigare Vizibilă"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Structurile de navigare și poligoanele vor fi vizibile când jocul rulează "
"dacă această opțiune este activată."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sincronizează Modificările Scenei"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Când această opțiune este activată, orice modificare facută în scenă din "
"editor va fi replicată în jocul care rulează.\n"
@@ -2853,15 +2881,17 @@ msgstr ""
"mult mai eficient dacă este folosit un sistem de fișiere în rețea."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sincronizează Modificările Scriptului"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Când această opțiune este activată, orice script salvat ulterior va fi "
"reîncărcat în jocul care rulează.\n"
@@ -2925,7 +2955,7 @@ msgstr "Ajutor"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Căutare"
@@ -3325,9 +3355,11 @@ msgid "Add Key/Value Pair"
msgstr ""
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Nu a fost găsită nicio presetare de export care să poată rula pentru această "
"platformă.\n"
@@ -5113,7 +5145,7 @@ msgid "Bake Lightmaps"
msgstr "Procesează Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Previzualizare"
@@ -7844,7 +7876,7 @@ msgid "New Animation"
msgstr "Animație"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9912,6 +9944,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10352,11 +10385,16 @@ msgid "Batch Rename"
msgstr "Redenumește"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Înlocuiți: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10404,7 +10442,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10463,8 +10501,9 @@ msgid "Reset"
msgstr "Resetați Zoom-area"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Folosiți expresii regulate"
#: editor/rename_dialog.cpp
msgid "At character %s"
@@ -12457,6 +12496,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12711,6 +12755,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Sistemul De Fișiere și încărcare Bare"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Când exporți sau lansezi, executabilul rezultat va încerca să se "
+#~ "conecteze la IP-ul acestui computer pentru a putea fi depanat."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Scena curentă nu a fost salvată niciodată, salvați-o înainte de rulare."
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 7b12d8195c..2c85fe4e8c 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -85,12 +85,14 @@
# kyanukovich <ianu0001@algonquinlive.com>, 2020.
# Ron788 <ustinov200511@gmail.com>, 2020.
# Daniel <dan.ef1999@gmail.com>, 2020.
+# NeoLan Qu <it.bulla@mail.ru>, 2020.
+# Nikita Epifanov <nikgreens@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-01 11:14+0000\n"
-"Last-Translator: Daniel <dan.ef1999@gmail.com>\n"
+"PO-Revision-Date: 2020-09-15 07:17+0000\n"
+"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -99,7 +101,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -304,7 +306,7 @@ msgstr "Продолжительность анимации (в секундах
#: editor/animation_track_editor.cpp
msgid "Add Track"
-msgstr "Добавить новый трек"
+msgstr "Добавить трек"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
@@ -325,7 +327,7 @@ msgstr "Дорожки анимации:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr "Изменить Путь Следования"
+msgstr "Изменить путь трека"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
@@ -333,7 +335,7 @@ msgstr "Включить/выключить этот трек."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "Режим Обновления (Как это свойство устанавливается)"
+msgstr "Режим обновления (как это свойство устанавливается)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -382,7 +384,7 @@ msgstr "Линейный"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr "Кубическая"
+msgstr "Кубический"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
@@ -609,6 +611,7 @@ msgid "Seconds"
msgstr "Секунды"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -787,7 +790,7 @@ msgstr "Учитывать регистр"
msgid "Whole Words"
msgstr "Целые слова"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Заменить"
@@ -980,6 +983,11 @@ msgid "Signals"
msgstr "Сигналы"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Фильтр тайлов"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Вы уверены, что хотите удалить все подключения от сигнала?"
@@ -1017,7 +1025,7 @@ msgid "Recent:"
msgstr "Недавнее:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Поиск:"
@@ -1197,6 +1205,9 @@ msgstr "Основатели Проекта"
msgid "Lead Developer"
msgstr "Ведущий разработчик"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Менеджер проектов "
@@ -1218,6 +1229,14 @@ msgid "Gold Sponsors"
msgstr "Золотые спонсоры"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Серебряные спонсоры"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Бронзовые спонсоры"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Мини спонсоры"
@@ -1693,16 +1712,17 @@ 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 "Панели «Файловая система» и «Импорт»"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Файловая система"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Панель «Импорт»"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1919,7 +1939,7 @@ msgstr "Режим отображения"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "Фокус на пути"
+msgstr "Переместить фокус на строку пути"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
@@ -1967,7 +1987,7 @@ msgstr "Каталоги и файлы:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Предпросмотр:"
@@ -2777,12 +2797,12 @@ msgstr "Набор тайлов..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Undo"
-msgstr "Отменить (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 "Повторить (Redo)"
+msgstr "Повторить"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
@@ -2844,24 +2864,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"При экспорте или развёртывании, полученный исполняемый файл будет пытаться "
-"подключиться к IP этого компьютера с целью отладки."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Небольшое развёртывание через сеть"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Когда эта опция включена, экспорт или развёртывание будет создавать "
"минимальный исполняемый файл.\n"
@@ -2874,9 +2898,10 @@ msgid "Visible Collision Shapes"
msgstr "Видимые области соприкосновения"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Когда эта опция включена, области соприкосновений и узлы Raycast(в 2D и 3D) "
"будут видимыми в запущенной игре."
@@ -2886,23 +2911,26 @@ msgid "Visible Navigation"
msgstr "Видимая навигация"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Когда эта опция включена, навигационные полисетки и полигоны будут видимыми "
"в запущенной игре."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Синхронизация изменений в сцене"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Когда эта опция включена, все изменения, внесённые на сцену, в редакторе "
"будут перенесены в запущенную игру.\n"
@@ -2910,15 +2938,17 @@ msgstr ""
"сетевой файловой системой."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Синхронизация изменений в скриптах"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Когда эта опция включена, любой сохранённый скрипт будет перезагружен в "
"запущенную игру.\n"
@@ -2982,7 +3012,7 @@ msgstr "Справка"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Поиск"
@@ -3401,9 +3431,11 @@ msgid "Add Key/Value Pair"
msgstr "Добавить пару: Ключ/Значение"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Не найден рабочий экспортер для этой платформы.\n"
"Пожалуйста, добавьте его в меню экспорта."
@@ -5168,7 +5200,7 @@ msgid "Bake Lightmaps"
msgstr "Запекать карты освещения"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Предпросмотр"
@@ -7815,7 +7847,8 @@ msgid "New Animation"
msgstr "Новая анимация"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Скорость (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -8952,7 +8985,7 @@ 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."
@@ -8960,11 +8993,11 @@ 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 "Returns the hyperbolic cosine of the parameter."
-msgstr "Возвращает гиперболический косинус аргумента."
+msgstr "Возвращает гиперболический косинус параметра."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8980,7 +9013,7 @@ 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."
@@ -8988,7 +9021,7 @@ 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."
@@ -9033,11 +9066,11 @@ msgstr "1.0 / скаляр"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer to the parameter."
-msgstr "Вычисляет ближайшее целое число."
+msgstr "Находит ближайшее к параметру целое число."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest even integer to the parameter."
-msgstr "Вычисляет ближайшее чётное число."
+msgstr "Находит ближайшее чётное число к параметру."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -9939,6 +9972,7 @@ msgstr ""
"Вы действительно хотите поискать существующие проекты Godot в %s папках?\n"
"Это может занять много времени."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Менеджер проектов"
@@ -10378,11 +10412,18 @@ msgid "Batch Rename"
msgstr "Групповое переименование"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Заменить: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Префикс"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Суффикс"
#: editor/rename_dialog.cpp
@@ -10430,7 +10471,8 @@ msgid "Per-level Counter"
msgstr "Счетчик для каждого уровня"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
"Если установить, счетчик перезапустится для каждой группы дочерних узлов"
@@ -10492,7 +10534,8 @@ msgid "Reset"
msgstr "Сбросить"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Ошибка в регулярном выражении"
#: editor/rename_dialog.cpp
@@ -12021,14 +12064,13 @@ msgstr "OpenJDK jarsigner не настроен в Настройках Реда
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
msgstr ""
-"Отладочная клавиатура не настроена ни в настройках редактора, ни в "
+"Отладочное хранилище ключей не настроено ни в настройках редактора, ни в "
"предустановках."
#: platform/android/export/export.cpp
msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
-"Отладочная клавиатура не настроена ни в настройках редактора, ни в "
-"предустановках."
+"Хранилище ключей не настроено ни в настройках редактора, ни в предустановках."
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
@@ -12574,6 +12616,11 @@ msgstr ""
"GIProbes не поддерживаются видеодрайвером GLES2.\n"
"Вместо этого используйте BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight с углом более 90 градусов не может отбрасывать тени."
@@ -12878,6 +12925,16 @@ msgstr "Изменения могут быть назначены только
msgid "Constants cannot be modified."
msgstr "Константы не могут быть изменены."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Панели «Файловая система» и «Импорт»"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "При экспорте или развёртывании, полученный исполняемый файл будет "
+#~ "пытаться подключиться к IP этого компьютера с целью отладки."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Текущая сцена никогда не была сохранена, сохраните её перед запуском."
diff --git a/editor/translations/si.po b/editor/translations/si.po
index c8b0a57cbe..d474b218ba 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -527,6 +527,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -706,7 +707,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -896,6 +897,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -933,7 +938,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1107,6 +1112,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1128,6 +1136,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1591,15 +1607,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1862,7 +1878,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2689,22 +2705,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2713,8 +2733,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2723,32 +2743,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2808,7 +2828,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3209,7 +3229,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4946,7 +4967,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7547,7 +7568,7 @@ msgid "New Animation"
msgstr "සජීවීකරණ පුනරාවර්ථනය"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9542,6 +9563,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9972,11 +9994,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10022,7 +10048,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10080,7 +10106,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12026,6 +12052,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 59cd8da671..9ef7eb1d1a 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-06-15 01:48+0000\n"
+"PO-Revision-Date: 2020-09-08 11:40+0000\n"
"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
"Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/"
"godot/sk/>\n"
@@ -23,7 +23,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.1-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -32,7 +32,7 @@ msgstr "Chybný argument convert(), použite TYPE_* konštanty."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "dĺžka očakávaného stringu 1 (písmeno)"
+msgstr "dĺžka očakávaného stringu 1 (písmeno)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -42,7 +42,7 @@ msgstr "Nedostatok bajtov na dekódovanie, alebo chybný formát."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "Neplatný vstup %i (neprešlo) vo výraze"
+msgstr "Nesprávny vstup(input) %i (neschválený) v požiadavke"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
@@ -98,7 +98,7 @@ msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr "zadarmo"
+msgstr "Voľný"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
@@ -118,7 +118,7 @@ msgstr "Hodnota:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr "Sem Vložte Kľúč"
+msgstr "Tu vložiť kľúč"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
@@ -130,7 +130,7 @@ msgstr "Zmazať označené kľúč(e)"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr "Pridať Bezierov bod"
+msgstr "Pridať Bezier bod"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
@@ -191,7 +191,7 @@ msgstr "Zmeniť Dĺžku Animácie (Change Animation Length)"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr "Zmeniť opakovanie Animácie (Change Animation Loop)"
+msgstr "Zmeniť Opakovanie Animácie"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -256,7 +256,7 @@ msgstr "Zapnúť/Vypnúť tento track."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "Update Mode (ako je nastavená táto možnosť)"
+msgstr "Update Mode (Tak ako je táto možnosť nastavená)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -517,7 +517,7 @@ msgstr "Zoskupte track-y pomocou node-u alebo ich zobrazte ako plain list."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr "Snap:"
+msgstr "Prichytiť:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -528,6 +528,7 @@ msgid "Seconds"
msgstr "Sekundy"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -706,7 +707,7 @@ msgstr "Match Case"
msgid "Whole Words"
msgstr "Celé slová"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Nahradiť"
@@ -756,9 +757,8 @@ msgid "Method in target node must be specified."
msgstr "Metóda v target node-e musí byť špecifikovaná."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method name must be a valid identifier."
-msgstr "Metóda v target node-e musí byť špecifikovaná."
+msgstr "Meno Metódy musí byť špecifikované."
#: editor/connections_dialog.cpp
msgid ""
@@ -898,6 +898,11 @@ msgid "Signals"
msgstr "Signály"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filter:"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Naozaj chcete odstrániť všetky pripojenia z tohto signálu?"
@@ -935,7 +940,7 @@ msgid "Recent:"
msgstr "Nedávne:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Hľadať:"
@@ -1115,6 +1120,9 @@ msgstr "Zakladatelia Projektu"
msgid "Lead Developer"
msgstr "Vedúci Vývojár"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Manažér Projektu "
@@ -1136,6 +1144,14 @@ msgid "Gold Sponsors"
msgstr "Zlatý Sponzori"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Strieborný Sponzori"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Bronzový Sponzori"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Malý Sponzori"
@@ -1611,16 +1627,17 @@ msgid "Scene Tree Editing"
msgstr "Editovanie Stromu Scén"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Importovať Dock"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Node Dock"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "Systém súborov a Import Dock-y"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "FileSystém"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Importovať Dock"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1884,9 +1901,9 @@ msgstr "Priečinky a Súbory:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
-msgstr "Ako to bude vyzerať:"
+msgstr "Predzobraziť:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File:"
@@ -2761,39 +2778,44 @@ msgstr "Deploy-ovanie z Remote Debug-om"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Pri exportovaní alebo deploy-ovaní, súbor resulting executable sa pokúsi o "
-"pripojenie do IP vášho počítača aby mohol byť debugg-ovaný."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Malý Deploy z Network FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Keď bude povolená táto možnosť, export alebo deploy vyprodukujú menej \n"
"súboru executable.\n"
-"Filesystém bude z projektu poskytovaný editorom v sieti. Na Androide, pre "
-"deploy budete potrebovať USB kábel \n"
-"rýchlejší výkon. Táto možnosť zrýchľuje proces testovania."
+"Filesystém bude z projektu poskytovaný editorom v sieti.\n"
+"Na Androide, predeploy budete potrebovať USB kábel pre rýchlejší výkon. Táto "
+"možnosť zrýchľuje proces testovania."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
msgstr "Viditeľné Tvary Kolízie"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Tvary Kolízie a raycast node-y (pre 2D a 3D) budú viditeľné po spustení hry "
"ak budete mať zapnutú túto možnosť."
@@ -2803,23 +2825,26 @@ msgid "Visible Navigation"
msgstr "Viditeľná Navigácia"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Navigačné mesh-e a polygony budú viditeľné po spustení hry ak budete mať "
"zapnutú túto možnosť."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Zmeny Synchronizácie Scény"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Keď zapnete túto možnosť, akékoľvek zmeny v scéne v editore budú náhradné so "
"spustenou hrou.\n"
@@ -2827,15 +2852,17 @@ msgstr ""
"filesystémom."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Zmeny Synchronizácie Scriptu"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Keď je zapnutá táto Možnosť, akýkoľvek uložený script bude znovu načítaný v "
"spustenej hre.\n"
@@ -2899,7 +2926,7 @@ msgstr "Pomoc"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Vyhľadať"
@@ -3053,19 +3080,19 @@ msgstr "Importovať Šablóny Zo ZIP File-u"
#: editor/editor_node.cpp
msgid "Template Package"
-msgstr "Balíček Šablón"
+msgstr "Balík Šablón"
#: editor/editor_node.cpp
msgid "Export Library"
-msgstr "Exportovať Library"
+msgstr "Exportovať Knižnicu"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr "Spojiť Z Existujúcim"
+msgstr "Zlúčiť s existujúcim"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
-msgstr "Otvoriť & Spustiť Script"
+msgstr "Otvoriť a vykonať skript"
#: editor/editor_node.cpp
msgid "New Inherited"
@@ -3105,7 +3132,7 @@ msgstr "Otvoriť predchádzajúci Editor"
#: editor/editor_node.h
msgid "Warning!"
-msgstr "Varovanie!"
+msgstr "Upozornenie!"
#: editor/editor_path.cpp
msgid "No sub-resources found."
@@ -3113,7 +3140,7 @@ msgstr "Nenašli sa žiadne \"sub-resources\"."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr "Vytváranie Zobrazenia \"Mesh-u\""
+msgstr "Vytváranie Predzobrazenia Mesh-u"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
@@ -3315,9 +3342,11 @@ msgid "Add Key/Value Pair"
msgstr "Pridať Kľúč/Hodnota \"Pair\""
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Pre túto platformu sa nenašiel žiadny spustiteľný \"export preset\" .\n"
"Prosím pridajte spustiteľný \"preset\" v export menu."
@@ -4223,7 +4252,7 @@ msgstr "Vyberte a premiestnite body, vytvorte body z RMB."
#: 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 "Povoliť snap a show grid."
+msgstr "Povoliť prichytenie a zobraziť mriežku."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4253,118 +4282,117 @@ msgstr "Pridať Trojuholník"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Change BlendSpace2D Limits"
-msgstr ""
+msgstr "Zmeniť Limity BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Change BlendSpace2D Labels"
-msgstr ""
+msgstr "Zmeniť Label BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Point"
-msgstr "Všetky vybrané"
+msgstr "Vymazať BlendSpace2D Bod"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Remove BlendSpace2D Triangle"
-msgstr ""
+msgstr "Vymazať BlendSpace2D Trojuholník"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "BlendSpace2D does not belong to an AnimationTree node."
-msgstr ""
+msgstr "BlendSpace2D nepatrí ku AnimationTree node."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "No triangles exist, so no blending can take place."
msgstr ""
+"Neexistujú žiadne trojuholníky, takže si nemôže zabrať miesto žiadny "
+"blending."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Toggle Auto Triangles"
-msgstr ""
+msgstr "Prepnúť Automatické Trojuholníky"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
-msgstr ""
+msgstr "Vytvoriť trojuholníky spájaním bodov."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
-msgstr ""
+msgstr "Vymazať body a trojuholníky."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
-msgstr ""
+msgstr "Vygenerovať blend trojuholníky Automaticky (nie manuálne)"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend:"
-msgstr ""
+msgstr "Blend:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Parameter Changed"
-msgstr ""
+msgstr "Parameter sa Zmenil"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filters"
-msgstr "Súbor:"
+msgstr "Upraviť Filtre"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
-msgstr ""
+msgstr "Nemôžete pridať output node do blend tree."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Add Node to BlendTree"
-msgstr ""
+msgstr "Pridať Node do BlendTree"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Node Moved"
-msgstr ""
+msgstr "Node sa pohol"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
-msgstr ""
+msgstr "Nepodarilo sa pripojiť, port sa možno používa alebo je neplatný."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Nodes Connected"
-msgstr ""
+msgstr "Node-y Spojené"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Nodes Disconnected"
-msgstr ""
+msgstr "Node-y Odpojené"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "Popis:"
+msgstr "Nastaviť Animáciu"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
-msgstr "Všetky vybrané"
+msgstr "Zmazať Node"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "Zmazať Node(y)"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Toggle Filter On/Off"
-msgstr ""
+msgstr "Zapnúť/Vypnúť Filter"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Change Filter"
-msgstr ""
+msgstr "Zmeniť Filter"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
msgstr ""
+"Nieje nastavený Animačný Prehrávač, takže sa nepodarilo získať mená trackov."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
-msgstr ""
+msgstr "Cesta prehrávača je neplatná, takže sa nepodarilo získať mená trackov."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4372,312 +4400,302 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
+"Animačný Prehrávač nemá žiadny platnú root node cestu, takže sa nepodarilo "
+"zistiť mená trackov."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Anim Clips"
-msgstr "Klipy Animácie:"
+msgstr "Klipy Animácie"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Zvukové Klipy:"
+msgstr "Zvukové Klipy"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "Funkcie:"
+msgstr "Funkcie"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Node Renamed"
-msgstr ""
+msgstr "Node Premenovaný"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node..."
-msgstr ""
+msgstr "Pridať Node..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filtered Tracks:"
-msgstr "Súbor:"
+msgstr "Upraviť Filtrované Tracky:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Enable Filtering"
-msgstr ""
+msgstr "Povoliť Filtrovanie"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
-msgstr ""
+msgstr "Prepnúť Autoplay"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
-msgstr ""
+msgstr "Nové Meno Animácie:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Anim"
-msgstr ""
+msgstr "Nová Animácia"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
-msgstr ""
+msgstr "Zmeniť Meno Animácie:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
-msgstr ""
+msgstr "Naozaj chcete vymazať Animáciu?"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Remove Animation"
-msgstr ""
+msgstr "Vymazať Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Invalid animation name!"
-msgstr ""
+msgstr "Meno animácie je Vadné!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation name already exists!"
-msgstr ""
+msgstr "Toto meno Animácie už existuje!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Rename Animation"
-msgstr ""
+msgstr "Premenovať Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
-msgstr ""
+msgstr "Blend sa Ďalej Zmenil"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
-msgstr ""
+msgstr "Zmeniť Blend Time"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Load Animation"
-msgstr ""
+msgstr "Načítať Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
-msgstr ""
+msgstr "Duplikovať Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to copy!"
-msgstr ""
+msgstr "Žiadne animácie na skopírovanie!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation resource on clipboard!"
-msgstr ""
+msgstr "Žiadny zroj animácie v clipboard!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
-msgstr ""
+msgstr "Prilepená Animácia"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Paste Animation"
-msgstr ""
+msgstr "Prilepiť Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to edit!"
-msgstr ""
+msgstr "Žiadna animácia na úpravu!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
-msgstr ""
+msgstr "Spusťiť vybranú animáciu odzadu z aktuálnej pozície. (A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr ""
+msgstr "Spustiť vybranú animáciu odzadu z konca. (Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
-msgstr ""
+msgstr "Zastaviť playback animácie. (S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
-msgstr ""
+msgstr "Spustiť vybranú animáciu od začiatku. (Shift+D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from current pos. (D)"
-msgstr ""
+msgstr "Spustiť vybranú animáciu z aktuálnej pozície. (D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation position (in seconds)."
-msgstr ""
+msgstr "Pozícia Animácie (v sekundách)."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Scale animation playback globally for the node."
-msgstr ""
+msgstr "Zväčšiť playback animácie globálne pre node."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
-msgstr ""
+msgstr "Animačné Náradie"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
msgstr "Animácie"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "Prechody"
+msgstr "Upraviť Prechody..."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Open in Inspector"
-msgstr "Otvorit priečinok"
+msgstr "Otvorit v Inšpektor-ovi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
-msgstr ""
+msgstr "Zobraziť list animácii v prehrávači."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Autoplay on Load"
-msgstr ""
+msgstr "Autoplay pri Načítaní"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Enable Onion Skinning"
-msgstr ""
+msgstr "Povoliť Onion Skinning"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Onion Skinning Options"
-msgstr ""
+msgstr "Onion Skinning Možnosti"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Directions"
-msgstr "Popis:"
+msgstr "Smery"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Past"
-msgstr "Vložiť"
+msgstr "Minulosť"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr ""
+msgstr "Budúcnosť"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
-msgstr ""
+msgstr "Hĺbka"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
-msgstr ""
+msgstr "1 krok"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "2 steps"
-msgstr ""
+msgstr "2 kroky"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "3 steps"
-msgstr ""
+msgstr "3 kroky"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Differences Only"
-msgstr ""
+msgstr "Iba Odlišnosti"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Force White Modulate"
-msgstr ""
+msgstr "Force White Modulate"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Include Gizmos (3D)"
-msgstr ""
+msgstr "Zahŕňa Gizmos (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pin AnimationPlayer"
-msgstr ""
+msgstr "Pripnúť Prehrávač Animácie"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
-msgstr ""
+msgstr "Vytvoriť Novú Animáciu"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
-msgstr ""
+msgstr "Meno Animácie:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
msgid "Error!"
-msgstr ""
+msgstr "Chyba!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Times:"
-msgstr ""
+msgstr "Blend Times:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Next (Auto Queue):"
-msgstr ""
+msgstr "Ďalej (Automatický Rad):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
-msgstr ""
+msgstr "Cross-Animation Blend Times"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "Vložiť"
+msgstr "Premiestniť Node"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Prechody"
+msgstr "Prechod existuje!"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "Prechody"
+msgstr "Pridať Prechod"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "Pridať Node"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
-msgstr ""
+msgstr "Koniec"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
-msgstr ""
+msgstr "Okamžite"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "Synchronizácia"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
-msgstr ""
+msgstr "Na Konci"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr ""
+msgstr "Cestovať"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Start and end nodes are needed for a sub-transition."
-msgstr ""
+msgstr "Pre sub-prechod je potrebné začať a skončiť node-y."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "No playback resource set at path: %s."
-msgstr ""
+msgstr "Nieje nastavený žiadny zdrojový playback ako cesta: %s."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Node Removed"
-msgstr ""
+msgstr "Node Zmazaný"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "Prechody"
+msgstr "Prechod Vymazaný"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
-msgstr ""
+msgstr "Nastaviť Začiatočný Node (Autoplay)"
#: editor/plugins/animation_state_machine_editor.cpp
msgid ""
@@ -4685,363 +4703,356 @@ msgid ""
"RMB to add new nodes.\n"
"Shift+LMB to create connections."
msgstr ""
+"Vybrať a premiestniť node-y.\n"
+"Pravím tlačítkom myši pridáte node-y.\n"
+"Shift+Lavé tlačíko myši vytvoriť pripojenie."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Create new nodes."
-msgstr "Vytvoriť adresár"
+msgstr "Vytvoriť Nové Node-y."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Connect nodes."
-msgstr ""
+msgstr "Spojiť Node-y."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Remove selected node or transition."
-msgstr "Odstrániť výber"
+msgstr "Vymazať označený node alebo prechod."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
+"Prepnúť autoplay na tejto animácii pri štarte, reštarte alebo seek to zero."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
-msgstr ""
+msgstr "Nastaviť koniec animácie. Toto je užitočné pre sub-prechody."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition: "
-msgstr "Prechody"
+msgstr "Prechody: "
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Play Mode:"
-msgstr "Cesta k Node:"
+msgstr "Prehrať Mód:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr ""
+msgstr "AnimačnýStrom"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
-msgstr ""
+msgstr "Nové Meno:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Scale:"
-msgstr ""
+msgstr "Veľkosť:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Fade In (s):"
-msgstr ""
+msgstr "Miznutie do (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Fade Out (s):"
-msgstr ""
+msgstr "Miznutie Von (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend"
-msgstr ""
+msgstr "Blend"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Mix"
-msgstr ""
+msgstr "Mix"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Auto Restart:"
-msgstr ""
+msgstr "Auto Reštart:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Restart (s):"
-msgstr ""
+msgstr "Reštart (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Random Restart (s):"
-msgstr ""
+msgstr "Náhodný Reštart (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Start!"
-msgstr ""
+msgstr "Štart!"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Amount:"
-msgstr ""
+msgstr "Množstvo:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend 0:"
-msgstr ""
+msgstr "Blend 0:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend 1:"
-msgstr ""
+msgstr "Blend 1:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "X-Fade Time (s):"
-msgstr ""
+msgstr "Čas X-Miznutia (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Current:"
-msgstr ""
+msgstr "Aktuálny:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Input"
-msgstr ""
+msgstr "Pridať Vstup"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Clear Auto-Advance"
-msgstr ""
+msgstr "Čistý Auto-Advance"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Set Auto-Advance"
-msgstr ""
+msgstr "Nastaviť Auto-Advance"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Delete Input"
-msgstr ""
+msgstr "Zmazať Vstup"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is valid."
-msgstr ""
+msgstr "Animačný Strom je platný."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is invalid."
-msgstr ""
+msgstr "Animačný Strom je neplatný."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation Node"
-msgstr ""
+msgstr "Animačný Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "OneShot Node"
-msgstr ""
+msgstr "OneShot Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Mix Node"
-msgstr ""
+msgstr "Mix Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend2 Node"
-msgstr ""
+msgstr "Blend2 Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend3 Node"
-msgstr ""
+msgstr "Blend3 Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend4 Node"
-msgstr ""
+msgstr "Blend4 Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "TimeScale Node"
-msgstr ""
+msgstr "TimeScale Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "TimeSeek Node"
-msgstr ""
+msgstr "TimeSeek Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Transition Node"
-msgstr ""
+msgstr "Prechodový Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Import Animations..."
-msgstr ""
+msgstr "Importovať Animácie..."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Edit Node Filters"
-msgstr ""
+msgstr "Nastaviť Node Filtre"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Filters..."
-msgstr ""
+msgstr "Filtre..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Contents:"
-msgstr "Konštanty:"
+msgstr "Obsah:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "View Files"
-msgstr "Súbor:"
+msgstr "Zobraziť Súbory"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
-msgstr ""
+msgstr "Chyba pripojenia, prosím skúste znovu."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't connect to host:"
-msgstr ""
+msgstr "Nepodarilo sa pripojiť k host:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No response from host:"
-msgstr ""
+msgstr "Žiadna odozva od host-a:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't resolve hostname:"
-msgstr ""
+msgstr "Nepodarilo sa rozlúštiť hostove meno:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
-msgstr ""
+msgstr "Žiadosť zlyhala, spätný kód:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed."
-msgstr ""
+msgstr "Žiadosť zlyhala."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Cannot save response to:"
-msgstr "Nemôžete odstrániť:"
+msgstr "Nepodarilo sa uložiť odpoveď do:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr ""
+msgstr "Chyba písania."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
-msgstr ""
+msgstr "Žiadosť zlyhala, príliš veľa presmerovaní"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect loop."
-msgstr ""
+msgstr "Presmerovací loop."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, timeout"
-msgstr ""
+msgstr "Žiadosť zlyhala, čas vypršal"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Timeout."
-msgstr "Čas:"
+msgstr "Čas vypršal."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
-msgstr ""
+msgstr "Zlý download hash, za predpokladu že bolo narábané so súborom."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
-msgstr ""
+msgstr "Očakávané:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Got:"
-msgstr ""
+msgstr "Má:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed sha256 hash check"
-msgstr ""
+msgstr "Zlyhalo sha256 hash check"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
-msgstr ""
+msgstr "Zlyhalo Sťahovanie Prostriedku:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Downloading (%s / %s)..."
-msgstr ""
+msgstr "Sťahovanie (%s / %s)..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Downloading..."
-msgstr ""
+msgstr "Sťahovanie..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Resolving..."
-msgstr ""
+msgstr "Rieši sa..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Error making request"
-msgstr ""
+msgstr "Pri vytváraní žiadosťi nastala chyba"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Idle"
-msgstr ""
+msgstr "Idle"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Install..."
-msgstr "Inštalovať"
+msgstr "Inštalovať..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
-msgstr ""
+msgstr "Skúsiť znova"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
-msgstr ""
+msgstr "Chyba Sťahovania"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download for this asset is already in progress!"
-msgstr ""
+msgstr "Sťahovanie tohoto prostriedku už prebieha!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "Nedávno Vylepšené"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr ""
+msgstr "Za Poslednú Dobu Najmenej Aktualizované"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "Meno (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "Meno (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "Licencia"
+msgstr "Licencia (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "Licencia"
+msgstr "Licencia (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "First"
-msgstr ""
+msgstr "Prvý"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Previous"
-msgstr ""
+msgstr "Minulý"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Next"
-msgstr ""
+msgstr "Ďalší"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Last"
-msgstr ""
+msgstr "Posledný"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "All"
-msgstr ""
+msgstr "Všetky"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr ""
+msgstr "Žiadne výsledky pre \"%s\"."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Import..."
-msgstr ""
+msgstr "Import..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Plugins..."
-msgstr ""
+msgstr "Pluginy..."
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
msgid "Sort:"
-msgstr ""
+msgstr "Zoradiť:"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
msgid "Category:"
-msgstr ""
+msgstr "Kategória:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Site:"
@@ -5049,23 +5060,23 @@ msgstr "Stránka:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Support"
-msgstr ""
+msgstr "Podpora"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
-msgstr ""
+msgstr "Oficiálne"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Testing"
-msgstr ""
+msgstr "Testovanie"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Loading..."
-msgstr ""
+msgstr "Načitávanie..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
-msgstr ""
+msgstr "Prostriedky Súboru ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5073,216 +5084,215 @@ msgid ""
"Save your scene (for images to be saved in the same dir), or pick a save "
"path from the BakedLightmap properties."
msgstr ""
+"Nedá sa určiť cesta pre uloženie lightmap obrázkov.\n"
+"Uložte svoju scénu (Aby sa obrázky na to isté miesto), alebo vyberte cestu "
+"na uloženie so BakedLightmap vlastností."
#: 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 ""
+"Žiadne mesh-e na bake. Uistite sa že obsahujú UV2 channel a je na ňom 'Bake "
+"Light' vlajka."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
+"Nepodarilo sa vytvoriť lightmap obrázok, uistite sa že či je cesta "
+"zapisovateľná."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr ""
+msgstr "Bake Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
-msgstr ""
+msgstr "Predzobraziť"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr ""
+msgstr "Konfigurovať Prichytenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr ""
+msgstr "Odchýlka Mriežky:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
-msgstr ""
+msgstr "Krok Mriežky:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "Všetky Primary Line:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "steps"
-msgstr ""
+msgstr "kroky"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
-msgstr ""
+msgstr "Odchýlka Rotácie:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
-msgstr ""
+msgstr "Krok Rotácie:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale Step:"
-msgstr "Zmeniť veľkosť výberu"
+msgstr "Krok Veľkosti:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Vertical Guide"
-msgstr "Popis:"
+msgstr "Presunúť Vertikálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Vertical Guide"
-msgstr "Popis:"
+msgstr "Vytvoriť Vertikálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Vertical Guide"
-msgstr "Všetky vybrané"
+msgstr "Vymazať Vertikálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Horizontal Guide"
-msgstr "Všetky vybrané"
+msgstr "Presunúť Horizontálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal Guide"
-msgstr "Popis:"
+msgstr "Vytvoriť Horizontálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Horizontal Guide"
-msgstr "Všetky vybrané"
+msgstr "Vymazať Horizontálny Návod"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal and Vertical Guides"
-msgstr "Popis:"
+msgstr "Vytvoriť Horizontálne a Vertikálne Návody"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move pivot"
-msgstr "Všetky vybrané"
+msgstr "Presunúť pivot"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotate CanvasItem"
-msgstr ""
+msgstr "Otočiť CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move anchor"
-msgstr ""
+msgstr "Presunúť kovadlinu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Resize CanvasItem"
-msgstr ""
+msgstr "Zmeniť Veľkosť CanvasItem-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale CanvasItem"
-msgstr ""
+msgstr "Veľkosť CanvasItem-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move CanvasItem"
-msgstr ""
+msgstr "Presunúť CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
"Children of containers have their anchors and margins values overridden by "
"their parent."
msgstr ""
+"Dieťa kontajnerov majú svoje kovadliny a okraje prepísané svojimi rodičmi."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Presets for the anchors and margins values of a Control node."
-msgstr ""
+msgstr "Prenastaviť pre kovadliny a okraje hodnoty Control node-u."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
+"Pri aktivovaní, pohybovanim Control node-ov zmeníte ich kovadliny namiesto "
+"ich okrajov."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Left"
-msgstr ""
+msgstr "Vľavo Hore"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Right"
-msgstr ""
+msgstr "Vpravo Hore"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Right"
-msgstr ""
+msgstr "Vpravo Dole"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Left"
-msgstr ""
+msgstr "Vľavo Dole"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Left"
-msgstr ""
+msgstr "Od Stredu Vľavo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Top"
-msgstr ""
+msgstr "Od Stredu Hore"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Right"
-msgstr ""
+msgstr "Od Stredu Vpravo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Bottom"
-msgstr ""
+msgstr "Od Stredu Dole"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
-msgstr ""
+msgstr "V Strede"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Left Wide"
-msgstr "Lineárne"
+msgstr "Ľavá Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Wide"
-msgstr ""
+msgstr "Horná Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Right Wide"
-msgstr "Lineárne"
+msgstr "Pravá Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Wide"
-msgstr ""
+msgstr "Dolná Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "VCenter Wide"
-msgstr ""
+msgstr "VerStredná Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "HCenter Wide"
-msgstr ""
+msgstr "HorStredná Šírka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Full Rect"
-msgstr ""
+msgstr "Plný Obdĺžnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Keep Ratio"
-msgstr ""
+msgstr "Udržovať Pomer"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
-msgstr ""
+msgstr "Iba Kovadliny"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors and Margins"
-msgstr ""
+msgstr "Zmeniť Kovadliny a Okraje"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors"
-msgstr ""
+msgstr "Zmeniť Kovadliny"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5290,6 +5300,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
+"Prepísanie Hernej Kamery\n"
+"Prepísať hernú kameru s viewport kamerou editora."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5297,104 +5309,103 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
+"Prepísanie Hernej Kamery\n"
+"Nieje spustená žiadna herná inštancia."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "Všetky vybrané"
+msgstr "Zamknúť Označené"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected"
-msgstr "Všetky vybrané"
+msgstr "Odomknúť Označené"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected"
-msgstr "Odstrániť výber"
+msgstr "Pridať Označené do Skupiny"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Odstrániť výber"
+msgstr "Odskupiť Označené"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
-msgstr ""
+msgstr "Prilepiť Pózu"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Guides"
-msgstr "Všetky vybrané"
+msgstr "Zmazať Návody"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
-msgstr ""
+msgstr "Vytvoriť Vlastnú Kosť(i) z Node-u(ou)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Bones"
-msgstr "Všetky vybrané"
+msgstr "Zmazať Kosti"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
-msgstr ""
+msgstr "Vytvoriť IK Reťaz"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear IK Chain"
-msgstr ""
+msgstr "Zmazať IK Reťaz"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
"Warning: Children of a container get their position and size determined only "
"by their parent."
msgstr ""
+"Upozornenie: Dieťa kontajnera získa ich pozíciu a veľkosť iba podľa svojho "
+"rodiča."
#: 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 ""
+msgstr "Resetovať Priblíženie"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
-msgstr ""
+msgstr "Vybrať Režim"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
-msgstr ""
+msgstr "Potiahnutím: Otáčenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move"
-msgstr ""
+msgstr "Alt+Potiahnutie: Pohyb"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
msgstr ""
+"Stačte 'v' pre Zmenu Pivot-a, 'Shift+v' pre hýbanie s Pivot-om (keď sa hýbe)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
-msgstr ""
+msgstr "Alt+RMB: Výber hĺbkového zoznamu"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
-msgstr ""
+msgstr "Move Mode"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
-msgstr ""
+msgstr "Rotačný Režim"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr ""
+msgstr "Zmena Veľkosti"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5402,187 +5413,186 @@ msgid ""
"Show a list of all objects at the position clicked\n"
"(same as Alt+RMB in select mode)."
msgstr ""
+"Zobraziť list všetkých objektov na kliknutej pozícii\n"
+"(rovnako ako Alt+RMB v výberovom režime)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Click to change object's rotation pivot."
-msgstr ""
+msgstr "Kliknite pre zmenu rotačného pivota objektu."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan Mode"
-msgstr ""
+msgstr "Pohyb Mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Ruler Mode"
-msgstr "Režim Interpolácie"
+msgstr "Pravítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle smart snapping."
-msgstr ""
+msgstr "Prepnúť smart prichytenie."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Smart Snap"
-msgstr ""
+msgstr "Použiť Smart Prichytenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle grid snapping."
-msgstr ""
+msgstr "Prepnúť Prichytenie Mriežky."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Grid Snap"
-msgstr ""
+msgstr "Použiť Príchyt Mriežky"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping Options"
-msgstr ""
+msgstr "Možnosti Prichytávania"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr ""
+msgstr "Použiť Prichytávanie Rotácie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Scale Snap"
-msgstr ""
+msgstr "Použiť Prichytávanie Veľkosti"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr ""
+msgstr "Prichytiť Relatívne"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
-msgstr ""
+msgstr "Použiť Pixelové Prichytenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Smart Snapping"
-msgstr ""
+msgstr "Smart Prichytávanie"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr ""
+msgstr "Konfigurovať Prichytávanie..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
-msgstr ""
+msgstr "Prichytiť na Rodiča"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Anchor"
-msgstr ""
+msgstr "Prichytiť na Kovadlinu Node-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Sides"
-msgstr ""
+msgstr "Prichitiť na strany Node-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Center"
-msgstr ""
+msgstr "Prichytiť na Stred Node-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
-msgstr "Vložiť"
+msgstr "Prichytiť na Ostatné Node-y"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Guides"
-msgstr ""
+msgstr "Prichytiť na Návody"
#: 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 ""
+msgstr "Zamknúť označený objekt na mieste (už sa s ním nebude dať hýbať)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock the selected object (can be moved)."
-msgstr ""
+msgstr "Odomknúť označený objekt (dá sa s ním hýbať)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Makes sure the object's children are not selectable."
-msgstr ""
+msgstr "Uistite sa že sa nedá označiť dieťa objektu."
#: 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 ""
+msgstr "Aby ste označili dieťa objektu tak mu musíte obnoviť schopnosť."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton Options"
-msgstr "Všetky vybrané"
+msgstr "Nastavenia Kostry"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Bones"
-msgstr ""
+msgstr "Zobraziť Kosti"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make Custom Bone(s) from Node(s)"
-msgstr ""
+msgstr "Vytvoriť Vlastnú Kosť(i) z Node-u(ou)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Custom Bones"
-msgstr ""
+msgstr "Zmazať Vlastné Kosti"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View"
-msgstr ""
+msgstr "Zobrazenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
-msgstr ""
+msgstr "Vždy Zobraziť Mriežku"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
-msgstr ""
+msgstr "Zobraziť Pomocníkov"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Rulers"
-msgstr ""
+msgstr "Zobraziť Pravítka"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Guides"
-msgstr ""
+msgstr "Zobraziť Návody"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Origin"
-msgstr ""
+msgstr "Zobraziť Pôvod"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Viewport"
-msgstr ""
+msgstr "Zobraziť Výrez"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
-msgstr ""
+msgstr "Zobraziť Skupinu a Zamknúť Ikony"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
-msgstr ""
+msgstr "Výber Stredu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr ""
+msgstr "Výber Frame-u"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
-msgstr ""
+msgstr "Predzobraziť Veľkosť Plátna"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
-msgstr ""
+msgstr "Prekladová maska na vkladanie kľúčov."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation mask for inserting keys."
-msgstr ""
+msgstr "Rotačná maska na vkladanie kľúčov."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale mask for inserting keys."
-msgstr ""
+msgstr "Veľkostná maska na vkladanie kľúčov."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert keys (based on mask)."
-msgstr ""
+msgstr "Vkladanie kľúčov (založené na maske)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5591,67 +5601,69 @@ 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 ""
+"Automaticky vložiť kľúče keď sú objekty preložené, rotované alebo zväčšené "
+"(založené na maske).\n"
+"Kľúče sú pridané iba do existujúcich track-ov, nebudú vytvorené žiadne nové "
+"tracky.\n"
+"Prvý krát musia byť kľúče vložené manuálne."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Auto Insert Key"
-msgstr "Animácia Vložiť Kľúč"
+msgstr "Automaticky Vložiť Kľúč"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Animation Key and Pose Options"
-msgstr "Dĺžka Času Animácie (v sekundách)"
+msgstr "Animačný Kľúč a Možnosti Pozície"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
-msgstr ""
+msgstr "Vložte Kľúč (Existujúce Tracky)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Copy Pose"
-msgstr ""
+msgstr "Kopírovať Pozíciu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
-msgstr ""
+msgstr "Zmazať Pozíciu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
-msgstr ""
+msgstr "Zdvojnásobiť krok mriežky dvomi"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Divide grid step by 2"
-msgstr ""
+msgstr "vydeliť krok mriežky dvomi"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan View"
-msgstr ""
+msgstr "Zobrazenie Pan"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
-msgstr ""
+msgstr "Pridať %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Adding %s..."
-msgstr ""
+msgstr "Pridávanie %s..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Cannot instantiate multiple nodes without root."
-msgstr ""
+msgstr "Nie je možné vytvoriť inštanciu viacerých node-ov bez koreňa."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Create Node"
-msgstr ""
+msgstr "Vytvoriť Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Error instancing scene from %s"
-msgstr ""
+msgstr "Chyba pri inštalácovaní scény z %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Change Default Type"
-msgstr "Zmeniť %s Typ"
+msgstr "Zmeniť Predvolený Typ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5660,214 +5672,204 @@ msgid ""
msgstr ""
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon3D"
-msgstr "Vytvoriť adresár"
+msgstr "Vytvoriť Polygon3D"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly"
-msgstr ""
+msgstr "Upraviť Poly"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly (Remove Point)"
-msgstr ""
+msgstr "Upraviť Poly (Odstrániť Bod)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
msgid "Set Handle"
-msgstr ""
+msgstr "Nastaviť Rukoväť"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
-msgstr ""
+msgstr "Načíť Emisnú Masku"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "Uložiť súbor"
+msgstr "Reštartovať"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Clear Emission Mask"
-msgstr ""
+msgstr "Zmazať Emisnú Masku"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Particles"
-msgstr ""
+msgstr "Particly"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Generated Point Count:"
-msgstr ""
+msgstr "Generovaný Bodový Počet:"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Mask"
-msgstr ""
+msgstr "Emisná Maska"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Solid Pixels"
-msgstr ""
+msgstr "Pevné Pixely"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Border Pixels"
-msgstr ""
+msgstr "Ohraničené Pixely"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Directed Border Pixels"
-msgstr "Priečinky a Súbory:"
+msgstr "Pixely s Priamym Ohraničením"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Capture from Pixel"
-msgstr ""
+msgstr "Snímanie z Pixelu"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Colors"
-msgstr ""
+msgstr "Emisné Farby"
#: editor/plugins/cpu_particles_editor_plugin.cpp
msgid "CPUParticles"
-msgstr ""
+msgstr "CPUParticly"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emission Points From Mesh"
-msgstr ""
+msgstr "Vytvoriť Emisné Body z Mesh-u"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emission Points From Node"
-msgstr ""
+msgstr "Vytvoriť Emisné Body z Node-u"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 0"
-msgstr ""
+msgstr "Plochý 0"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 1"
-msgstr ""
+msgstr "Plochý 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
-msgstr ""
+msgstr "Zvyšovanie"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease Out"
-msgstr ""
+msgstr "Znižovanie"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Smoothstep"
-msgstr ""
+msgstr "Hladkýkrok"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Point"
-msgstr ""
+msgstr "Modifikovať Bod Krivky"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Tangent"
-msgstr ""
+msgstr "Modifikovať Tangetu Krivky"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Load Curve Preset"
-msgstr ""
+msgstr "Načítať Predvoľbu Krivky"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
-msgstr "Signály:"
+msgstr "Pridať Bod"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
-msgstr "Všetky vybrané"
+msgstr "Vymazať Bod"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Left Linear"
-msgstr "Lineárne"
+msgstr "Lineárne Vľavo"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right Linear"
-msgstr "Lineárne"
+msgstr "Lineárne Vpravo"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Load Preset"
-msgstr "Načítať predvolené"
+msgstr "Načítať Predvoľbu"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Curve Point"
-msgstr "Všetky vybrané"
+msgstr "Vymazať Bod Krivky"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Toggle Curve Linear Tangent"
-msgstr ""
+msgstr "Prepnúť Lineárnu Tangetu Krivky"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Hold Shift to edit tangents individually"
-msgstr ""
+msgstr "Podržte Shift aby ste upravili tangetu individuálne"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Right click to add point"
-msgstr ""
+msgstr "Pravým kliknutím pridáťe Bod"
#: editor/plugins/gi_probe_editor_plugin.cpp
msgid "Bake GI Probe"
-msgstr ""
+msgstr "Vypiecť GI Probe"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
-msgstr ""
+msgstr "Prechod je Upravený"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
-msgstr ""
+msgstr "Predmet %d"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Items"
-msgstr ""
+msgstr "Predmety"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item List Editor"
-msgstr ""
+msgstr "List Editor Predmetov"
#: editor/plugins/light_occluder_2d_editor_plugin.cpp
msgid "Create Occluder Polygon"
-msgstr ""
+msgstr "Vytvoriť Occluder Polygon"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
-msgstr ""
+msgstr "Mesh je prázdny!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create a Trimesh collision shape."
-msgstr "Vytvoriť adresár"
+msgstr "Nepodarilo sa vytvoriť Trimesh collision shape."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
-msgstr ""
+msgstr "Vytvoriť Static Trimesh Telo"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
-msgstr ""
+msgstr "Toto nefunguje na koreni scény!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Shape"
-msgstr ""
+msgstr "Vytvoriť Trimesh Static Shape"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create a single convex collision shape for the scene root."
@@ -6529,11 +6531,11 @@ msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
-msgstr ""
+msgstr "Prichytiť"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr ""
+msgstr "Povoliť Prichytávanie"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
@@ -7356,7 +7358,7 @@ msgstr "Filter:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
-msgstr ""
+msgstr "Filmové Predzobrazenie"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Not available when using the GLES2 renderer."
@@ -7419,11 +7421,11 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
-msgstr ""
+msgstr "Prichytiť Node-y Na Zem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
-msgstr ""
+msgstr "Nepodarilo sa nájsť pevnú zem na prichytenie výberu."
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7438,7 +7440,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
-msgstr ""
+msgstr "Použiť Prichytávanie"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
@@ -7492,7 +7494,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
-msgstr ""
+msgstr "Prichytiť Objekt na Zem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
@@ -7541,19 +7543,19 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
-msgstr ""
+msgstr "Nastavenie Prichytenia"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate Snap:"
-msgstr ""
+msgstr "Preložiť Preloženie:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr ""
+msgstr "Prichytenie Rotácie (v stupňoch.):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
-msgstr ""
+msgstr "Prichytenie Veľkosti (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
@@ -7610,7 +7612,7 @@ msgstr "Vytvoriť adresár"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Mesh2D Preview"
-msgstr ""
+msgstr "Predzobraziť Mash2D"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7619,7 +7621,7 @@ msgstr "Vytvoriť adresár"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Polygon2D Preview"
-msgstr ""
+msgstr "Predzobraziť Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7627,9 +7629,8 @@ msgid "Create CollisionPolygon2D"
msgstr "Vytvoriť adresár"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "CollisionPolygon2D Preview"
-msgstr "Vytvoriť adresár"
+msgstr "Predzobraziť CollisionPolygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7637,9 +7638,8 @@ msgid "Create LightOccluder2D"
msgstr "Vytvoriť adresár"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "LightOccluder2D Preview"
-msgstr "Vytvoriť adresár"
+msgstr "Predzobraziť LightOccluder2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite is empty!"
@@ -7701,7 +7701,7 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Update Preview"
-msgstr ""
+msgstr "Predzobraziť Vylepšenie"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Settings:"
@@ -7763,7 +7763,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -7835,7 +7835,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr ""
+msgstr "Režim Prichytenia:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
@@ -7844,11 +7844,11 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr ""
+msgstr "Prichytenie Pixelov"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr ""
+msgstr "Prichytenie Mriežky"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
@@ -8274,6 +8274,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
msgstr ""
+"Povoliť prichytávanie a zobraziť mriežku (konfigurovatelné cez inšpektor)."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
@@ -8322,11 +8323,12 @@ msgid "Delete selected Rect."
msgstr "Všetky vybrané"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select current edited sub-tile.\n"
"Click on another Tile to edit it."
-msgstr "Vytvoriť adresár"
+msgstr ""
+"Vybrať aktuálne upravený pod-nadpis.\n"
+"Kliknite na ďalší Nadpis aby ste ho upravili."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8334,13 +8336,16 @@ msgid "Delete polygon."
msgstr "Všetky vybrané"
#: 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 "Vytvoriť adresár"
+msgstr ""
+"LMB: Zapnúť bit.\n"
+"RMB: Vypnúť bit.\n"
+"Shift+LMB: Nastaviť wildcard bit.\n"
+"Kliknite na ďalší Nadpis pre úpravu."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8356,11 +8361,12 @@ msgid ""
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 "Vytvoriť adresár"
+msgstr ""
+"Vybrať podnadpis aby ste zmenili jeho index.\n"
+"Kliknite na ďalší Nadpis na úpravu."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Region"
@@ -9832,6 +9838,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10273,11 +10280,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Nahradiť: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10323,7 +10335,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10381,7 +10393,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10488,14 +10500,12 @@ msgid "Make node as Root"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Všetky vybrané"
+msgstr "Zmazať %d node-y a nejaké deti?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Všetky vybrané"
+msgstr "Zmazať %d node-y?"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10506,9 +10516,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Všetky vybrané"
+msgstr "Zmazať node \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -10711,9 +10720,8 @@ msgid "Button Group"
msgstr "Tlačidlo"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "Pripojiť Signál: "
+msgstr "(Pripájanie z)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
@@ -10917,9 +10925,8 @@ msgid "Attach Node Script"
msgstr "Popis:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Remote "
-msgstr "Všetky vybrané"
+msgstr "Diaľkový "
#: editor/script_editor_debugger.cpp
msgid "Bytes:"
@@ -11312,7 +11319,7 @@ msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Snap View"
-msgstr ""
+msgstr "Prichytiť Zobrazenie"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clip Disabled"
@@ -12361,13 +12368,12 @@ msgid ""
msgstr ""
#: scene/3d/collision_shape.cpp
-#, fuzzy
msgid ""
"A shape must be provided for CollisionShape to function. Please create a "
"shape resource for it."
msgstr ""
-"Musíte nastaviť tvar objektu CollisionShape2D aby fungoval. Prosím, vytvorte "
-"preň tvarový objekt!"
+"Aby CollisionShape fungoval musíte nastaviť tvar. Prosím, vytvorte preň "
+"tvarový objekt."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -12400,6 +12406,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12625,9 +12636,8 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Nesprávna veľkosť písma."
+msgstr "Neplatný zdroj pre predzobrazenie."
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
@@ -12655,6 +12665,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Systém súborov a Import Dock-y"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Pri exportovaní alebo deploy-ovaní, súbor resulting executable sa pokúsi "
+#~ "o pripojenie do IP vášho počítača aby mohol byť debugg-ovaný."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Aktuálna scéna sa nikdy neuložila, prosím uložte ju pred spustením."
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index c40bc3b40f..a97fb1ae39 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -555,6 +555,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -743,7 +744,7 @@ msgstr "Ujemanje Velikih Črk"
msgid "Whole Words"
msgstr "Cele Besede"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Zamenjaj"
@@ -947,6 +948,11 @@ msgid "Signals"
msgstr "Signali"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtriraj datoteke..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -987,7 +993,7 @@ msgid "Recent:"
msgstr "Nedavni:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Iskanje:"
@@ -1172,6 +1178,9 @@ msgstr "Ustanovitelji Projekta"
msgid "Lead Developer"
msgstr "Vodilni Razvajalec"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Upravljalnik Projekta "
@@ -1193,6 +1202,16 @@ msgid "Gold Sponsors"
msgstr "Zlati Sponzorji"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Srebrni Donatorji"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronasti Donatorji"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Majhni Sponzorji"
@@ -1681,21 +1700,21 @@ msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Uvozi"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "Način Premika"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "DatotečniSistem"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "Uvozi"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "Zamenjaj Vse"
@@ -1984,7 +2003,7 @@ msgstr "Mape & Datoteke:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Predogled:"
@@ -2894,24 +2913,28 @@ msgstr "Uvajanje z Oddaljenim Razhroščevanjem"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Pri izvažanju ali uvajanju se bo končna izvršljiva datoteka razhroščevala, "
-"tako da se bo skušala povezati z IP-jem tega računalnika."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Kratko Uvajanje z Omrežjem FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Ko je ta možnost omogočena, se bo pri izvozu ali uvajanju ustvarila "
"minimalna izvršljiva datoteka.\n"
@@ -2924,9 +2947,10 @@ msgid "Visible Collision Shapes"
msgstr "Vidne Oblike Trka"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Gradniki oblike trka in prikaz žarka (za 2D in 3D) bodo vidni pri poteku "
"igre, če je ta možnost vklopljena."
@@ -2936,37 +2960,42 @@ msgid "Visible Navigation"
msgstr "Vidna Navigacija"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Če je ta možnost vključena, bodo navigacijske oblike in poligoni vidni pri "
"poteku igre."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Usklajuj Spremembe Prizora"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Ko je ta možnost vključena, bodo vse spremebe v prizoru ali urejevalniku "
"ponovljene med potekom igre."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Usklajuj Spremembe Skript"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Če je ta možnost vključena, bo vsaka shranjena skripta ponovno naložena v "
"igro, ki se izvaja.\n"
@@ -3038,7 +3067,7 @@ msgstr "Pomoč"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Iskanje"
@@ -3453,9 +3482,11 @@ msgid "Add Key/Value Pair"
msgstr ""
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Za to platformo ni mogoče najti obstoječih izvoznih nastavitev.\n"
"V izvoznem meniju dodajte svoje nastavitve."
@@ -5325,7 +5356,7 @@ msgid "Bake Lightmaps"
msgstr "Zapeči Svetlobne karte"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Predogled"
@@ -8065,7 +8096,7 @@ msgid "New Animation"
msgstr "Animacija"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10166,6 +10197,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Upravljalnik Projekta"
@@ -10606,11 +10638,16 @@ msgid "Batch Rename"
msgstr "Preimenuj"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Zamenjaj"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10662,7 +10699,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10722,8 +10759,9 @@ msgid "Reset"
msgstr "Ponastavi Povečavo/Pomanjšavo"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Trenutna Različica:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12775,6 +12813,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13042,6 +13085,17 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstante ni možno spreminjati."
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "DatotečniSistem"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Pri izvažanju ali uvajanju se bo končna izvršljiva datoteka "
+#~ "razhroščevala, tako da se bo skušala povezati z IP-jem tega računalnika."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Trenutna scena ni bila shranjena, shranite jo pred zagonom."
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 2df44bdd5b..6dd423a048 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -513,6 +513,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -694,7 +695,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -892,6 +893,11 @@ msgid "Signals"
msgstr "Sinjalet"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtro Skedarët..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "A jeni i sigurt që doni të hiqni të gjitha lidhjet nga ky sinjal?"
@@ -929,7 +935,7 @@ msgid "Recent:"
msgstr "Të fundit:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Kërko:"
@@ -1114,6 +1120,9 @@ msgstr "Themeluesit e Projektit"
msgid "Lead Developer"
msgstr "Krye Zhvilluesi"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Menaxheri Projektit "
@@ -1135,6 +1144,16 @@ msgid "Gold Sponsors"
msgstr "Sponsorat Flori"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Dhuruesit Argjend"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Dhuruesit Bronz"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsorat"
@@ -1628,21 +1647,21 @@ msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Importo"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "Nyje"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "FileSystem"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "Importo"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "Zëvendëso të gjitha (pa kthim pas)"
@@ -1921,7 +1940,7 @@ msgstr "Direktorit & Skedarët:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Shikim paraprak:"
@@ -2823,24 +2842,28 @@ msgstr "Dorëzo me Rregullim në Largësi"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Kur eksporton ose dorëzon, rezultati i ekzekutueshëm do të tentoj të lidhet "
-"me IP-në e këtij kompjuteri në mënyrë që të rregullohet."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Dorëzim i Vogël me Rrjet FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Kur ky opsion është i aktivizuar, eksportimi ose dorëzimi do të prodhojë një "
"të ekzekutueshëm minimal.\n"
@@ -2853,9 +2876,10 @@ msgid "Visible Collision Shapes"
msgstr "Format e Përplasjes të Dukshme"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Format e përplasjes dhe nyjet 'raycast' (për 2D dhe 3D) do të jenë të "
"dukshme gjatë ekzekutimit të lojës nëse ky opsion është i aktivizuar."
@@ -2865,38 +2889,43 @@ msgid "Visible Navigation"
msgstr "Navigim i Dukshëm"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Rrjetat e navigimit dhe poligonet do të jenë të dukshme gjatë lojës nëse ky "
"opsion është i aktivizuar."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sinkronizo Nryshimet e Skenës"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kur ky opsion është i aktivizuar, çdo ndryshim i bërë në këtë skenë do të "
"kopjohet dhe në lojën duke u ekzekutuar.\n"
"Kur përdoret në largësi është më efikas me rrjet 'filesystem'."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Sinkronizo Ndryshimet e Shkrimit"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Kurbky opsion është aktivizuar, çdo shkrim që ruhet do të ringarkohet në "
"lojën që është duke u ekzekutuar.\n"
@@ -2965,7 +2994,7 @@ msgstr "Ndihmë"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Kërko"
@@ -3381,9 +3410,11 @@ msgid "Add Key/Value Pair"
msgstr "Shto Palë Çelës/Vlerë"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Nuk u gjet eksport paraprak i saktë për këtë platformë.\n"
"Ju lutem shtoni një eksport paraprak të saktë në menu."
@@ -5166,7 +5197,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7798,7 +7829,7 @@ msgid "New Animation"
msgstr "Animacionin i Ri"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9817,6 +9848,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10250,11 +10282,16 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Zëvendëso: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10301,7 +10338,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10359,8 +10396,9 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Versioni Aktual:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12345,6 +12383,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12596,6 +12639,17 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "FileSystem"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Kur eksporton ose dorëzon, rezultati i ekzekutueshëm do të tentoj të "
+#~ "lidhet me IP-në e këtij kompjuteri në mënyrë që të rregullohet."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Skena aktuale nuk është ruajtur më parë, ju lutem ruajeni para se të "
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 0bb67647f8..1c68f56270 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -593,6 +593,7 @@ msgid "Seconds"
msgstr "Секунди"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -786,7 +787,7 @@ msgstr "Подударање великих и малих слова"
msgid "Whole Words"
msgstr "Целе речи"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Замени"
@@ -999,6 +1000,11 @@ msgstr "Сигнали"
#: editor/connections_dialog.cpp
#, fuzzy
+msgid "Filter signals"
+msgstr "Филтрирај датотеке..."
+
+#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Сугурно желиш да уклониш све везе са овог сигнала?"
@@ -1042,7 +1048,7 @@ msgid "Recent:"
msgstr "Честе:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Тражи:"
@@ -1228,6 +1234,9 @@ msgstr "Оснивачи пројекта"
msgid "Lead Developer"
msgstr "Главни девелопер"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
#, fuzzy
msgid "Project Manager "
@@ -1250,6 +1259,16 @@ msgid "Gold Sponsors"
msgstr "Златни спонзори"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Сребрни донатори"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Бронзани донатори"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Мали спонзори"
@@ -1759,21 +1778,21 @@ msgstr "Едитовање Стабла Сцене"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Увоз"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "Режим померања"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "Датотечни систем"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "Увоз"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "Замени све"
@@ -2068,7 +2087,7 @@ msgstr "Директоријуми и датотеке:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Преглед:"
@@ -3008,24 +3027,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"При извозу или извршавању, крајља датотека ће покушати да се повеже са "
-"адресом овог рачунара како би се могла дебаговати."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Мали извоз са Network FS"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Када је ова опција укључена, извоз ће правити датотеку најмање могуће "
"величине.\n"
@@ -3038,9 +3061,10 @@ msgid "Visible Collision Shapes"
msgstr "Видљиви облици судара"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Облици судара и чворова зракова (за 2Д и 3Д) ћу бити видљиви током игре ако "
"је ова опција укључена."
@@ -3050,23 +3074,26 @@ msgid "Visible Navigation"
msgstr "Видљива навигација"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Навигационе мреже и полигони ће бити видљиви током игре ако је ова опција "
"укључена."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Синхронизуј промене сцене"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Када је ова опција укључена, све промене сцене ће бити приказане у "
"покренутој игри.\n"
@@ -3074,15 +3101,17 @@ msgstr ""
"мрежним датотечним системом."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Синхронизуј промене скриптица"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Када је ова опција укључена, све скриптице које се сачувају ће бити поново "
"учитане у покренутој игри.\n"
@@ -3155,7 +3184,7 @@ msgstr "Помоћ"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Тражи"
@@ -3615,9 +3644,11 @@ msgid "Add Key/Value Pair"
msgstr "Додај Кључ/Вредност пар"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Нису пронађене поставке извоза за ову платформу.\n"
"Молим, додајте поставке у менију за извоз."
@@ -5579,7 +5610,7 @@ msgid "Bake Lightmaps"
msgstr "Изпеци МапеСенчења"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Преглед"
@@ -8496,7 +8527,8 @@ msgid "New Animation"
msgstr "Анимација"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Брзина (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10994,6 +11026,7 @@ msgstr ""
"пројектима?\n"
"Ово може потрајати."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Менаџер пројекта"
@@ -11535,12 +11568,17 @@ msgstr "Преименуј Гомилу"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Prefix"
+msgid "Replace:"
+msgstr "Замени"
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Предметак"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Suffix"
+msgid "Suffix:"
msgstr "Наставак"
#: editor/rename_dialog.cpp
@@ -11597,7 +11635,7 @@ msgstr "Пред-Ниво Бројач"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Ако је постављен, бројач се рестартује за сваку групу деце чворова"
#: editor/rename_dialog.cpp
@@ -11671,7 +11709,7 @@ msgstr "Ресетуј увеличање"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "Регуларни Израз Грешка"
#: editor/rename_dialog.cpp
@@ -14096,6 +14134,11 @@ msgstr ""
" \n"
"Као замену користи ИспеченеСенкеМапу."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
#, fuzzy
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -14442,6 +14485,17 @@ msgstr "Варијације могу само бити одређене у фу
msgid "Constants cannot be modified."
msgstr "Константе није могуће мењати."
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Датотечни систем"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "При извозу или извршавању, крајља датотека ће покушати да се повеже са "
+#~ "адресом овог рачунара како би се могла дебаговати."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Тренутна сцена није сачувана, молим сачувајте је пре покретања."
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 4dece6c33c..ad26751fe5 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -531,6 +531,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -715,7 +716,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -905,6 +906,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -942,7 +947,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1116,6 +1121,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1137,6 +1145,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1600,15 +1616,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1874,7 +1890,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2704,22 +2720,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2728,8 +2748,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2738,32 +2758,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2824,7 +2844,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3226,7 +3246,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4970,7 +4991,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7594,7 +7615,7 @@ msgid "New Animation"
msgstr "Optimizuj Animaciju"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9617,6 +9638,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10051,11 +10073,15 @@ msgid "Batch Rename"
msgstr "Animacija Preimenuj Kanal"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10101,7 +10127,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10159,7 +10185,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12114,6 +12140,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index d3cda1a61a..ff50441f17 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -17,12 +17,13 @@
# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020.
# Jonas Robertsson <jonas.robertsson@posteo.net>, 2020.
# André Andersson <andre.eric.andersson@gmail.com>, 2020.
+# Andreas Westrell <andreas.westrell@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-15 02:42+0000\n"
-"Last-Translator: Jonas Robertsson <jonas.robertsson@posteo.net>\n"
+"PO-Revision-Date: 2020-08-18 02:54+0000\n"
+"Last-Translator: Andreas Westrell <andreas.westrell@gmail.com>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
"Language: sv\n"
@@ -539,6 +540,7 @@ msgid "Seconds"
msgstr "Sekunder"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -717,7 +719,7 @@ msgstr "Matcha gemener/versaler"
msgid "Whole Words"
msgstr "Hela Ord"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Ersätt"
@@ -910,6 +912,11 @@ msgid "Signals"
msgstr "Signaler"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Filtrera Filer..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Är du säker att du vill ta bort alla kopplingar från denna signal?"
@@ -947,7 +954,7 @@ msgid "Recent:"
msgstr "Senaste:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Sök:"
@@ -1129,9 +1136,12 @@ msgstr "Projektgrundare"
msgid "Lead Developer"
msgstr "Ledande utvecklare"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
-msgstr "Projekthanterare "
+msgstr "Projektledare "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1150,6 +1160,16 @@ msgid "Gold Sponsors"
msgstr "Guldsponsorer"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Silverdonatorer"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronsdonatorer"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Minisponsorer"
@@ -1231,9 +1251,8 @@ msgid "Success!"
msgstr "Klart!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "Innehåll:"
+msgstr "Packet Innehåll:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1256,9 +1275,8 @@ msgid "Rename Audio Bus"
msgstr "Byt namn på Ljud-Buss"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Change Audio Bus Volume"
-msgstr "Växla Ljud-Buss Solo"
+msgstr "Växla Ljud-Buss Volum"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
@@ -1385,9 +1403,8 @@ msgid "Add Bus"
msgstr "Lägg till Buss"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Add a new Audio Bus to this layout."
-msgstr "Spara Ljud-Buss Layout Som..."
+msgstr "Lägg till en ny Audio-Buss för detta layout"
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1639,17 +1656,18 @@ msgstr "Scenträd (Noder):"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "Importera"
+msgid "Node Dock"
+msgstr "Node Namn:"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Node Dock"
-msgstr "Node Namn:"
+msgid "FileSystem Dock"
+msgstr "FilSystem"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr ""
+#, fuzzy
+msgid "Import Dock"
+msgstr "Importera"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1937,7 +1955,7 @@ msgstr "Kataloger & Filer:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Förhandsvisning:"
@@ -2854,22 +2872,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2878,8 +2900,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2888,32 +2910,34 @@ msgstr "Synlig Navigation"
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Synkronisera scenändringar"
#: 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Synkronisera skriptändringar"
#: 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2976,7 +3000,7 @@ msgstr "Hjälp"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Sök"
@@ -3395,7 +3419,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5243,7 +5268,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Förhandsgranska"
@@ -7961,7 +7986,7 @@ msgid "New Animation"
msgstr "Animation"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10059,6 +10084,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projektledare"
@@ -10498,11 +10524,16 @@ msgid "Batch Rename"
msgstr "Byt namn"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Ersätt:"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10554,7 +10585,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10616,8 +10647,9 @@ msgid "Reset"
msgstr "Återställ Zoom"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Nuvarande Version:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12668,6 +12700,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index 01cbcc1881..bff90ce603 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -4,13 +4,14 @@
# This file is distributed under the same license as the Godot source code.
#
# Senthil Kumar K <logickumar@gmail.com>, 2017.
-#
+# Survesh VRL <123survesh@gmail.com>, 2020.
+# Sridhar <sreeafmarketing@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-12-13 14:43+0100\n"
-"Last-Translator: Senthil Kumar K <logickumar@gmail.com>\n"
+"PO-Revision-Date: 2020-09-01 10:38+0000\n"
+"Last-Translator: Sridhar <sreeafmarketing@gmail.com>\n"
"Language-Team: Tamil <https://hosted.weblate.org/projects/godot-engine/godot/"
"ta/>\n"
"Language: ta\n"
@@ -18,34 +19,37 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Poedit 2.2\n"
+"X-Generator: Weblate 4.2.1-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 ""
+msgstr "தவறான வகை வாதம் மாற்று(), TYPE_ * மாறிலிகளைப் பயன்படுத்தவும்."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+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 ""
+msgstr "டிகோடிங் போதுமான பைட்டுகள் இல்லை, அல்லது தவறான வடிவத்தில் உள்ளது."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "தவறான உள்ளீடு% i (அனுப்பப்படவில்லை) இல் வெளிப்பாட்டில்"
#: core/math/expression.cpp
+#, fuzzy
msgid "self can't be used because instance is null (not passed)"
msgstr ""
+"சுயத்தை பயன்படுத்த முடியாது, ஏனெனில் உதாரணம்(instance) பூஜ்யமானது "
+"(நிறைவேற்றப்படவில்லை)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "ஆபரேட்டர்% s,% s மற்றும்% s க்கு தவறான செயல்பாடுகள் உள்ளது."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
@@ -526,6 +530,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -707,7 +712,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -897,6 +902,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -934,7 +943,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1108,6 +1117,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1129,6 +1141,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1592,15 +1612,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1864,7 +1884,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2691,22 +2711,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2715,8 +2739,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2725,32 +2749,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2811,7 +2835,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3212,7 +3236,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4950,7 +4975,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7545,7 +7570,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9536,6 +9561,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9968,11 +9994,15 @@ msgid "Batch Rename"
msgstr "அசைவூட்டு பாதைக்கு மறுபெயர் இடு"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10018,7 +10048,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10076,7 +10106,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12020,6 +12050,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 3523306b0d..2c6d8146e2 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -2,11 +2,11 @@
# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
-# suresh p <suresh9247@gmail.com>, 2019.
+# suresh p <suresh9247@gmail.com>, 2019, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-01-16 20:20+0000\n"
+"PO-Revision-Date: 2020-09-15 07:17+0000\n"
"Last-Translator: suresh p <suresh9247@gmail.com>\n"
"Language-Team: Telugu <https://hosted.weblate.org/projects/godot-engine/"
"godot/te/>\n"
@@ -14,16 +14,17 @@ msgstr ""
"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.4-dev\n"
+"X-Generator: Weblate 4.3-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 ""
+"() కు మార్చడానికి ఈ వాదన (argument) సరికాదు, దానికి TYPE_* స్థిరాంకాలను(constants) ఉపయోగించండి."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "స్ట్రింగ్(string ) యొక్క పొడవు 1 అక్షరం మాత్రమే ఆశిస్తుంది."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -39,11 +40,11 @@ msgstr "వ్యక్తీకరణలో చెల్లని ఇన్ప
#: core/math/expression.cpp
#, fuzzy
msgid "self can't be used because instance is null (not passed)"
-msgstr "తనకు తానుగా ఉపయోగించుకోలేదు ఎందుకంటే instance ఒక శూన్యం (ఆమోదించబడలేదు )"
+msgstr "తనకు తానుగా(self) ఉపయోగించుకోలేదు ఎందుకంటే instance ఒక శూన్యం (ఆమోదించబడలేదు )"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "oparator % s,% s మరియు % s కు చెల్లని oparands."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
@@ -508,6 +509,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -686,7 +688,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -875,6 +877,10 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -912,7 +918,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1086,6 +1092,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1107,6 +1116,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1570,15 +1587,15 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
+msgid "Node Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Node Dock"
+msgid "FileSystem Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1841,7 +1858,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2666,22 +2683,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2690,8 +2711,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2700,32 +2721,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2785,7 +2806,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3185,7 +3206,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -4909,7 +4931,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7491,7 +7513,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9468,6 +9490,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -9898,11 +9921,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -9948,7 +9975,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10006,7 +10033,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -11935,6 +11962,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 279f8c08ba..d1afffd2cd 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -6,12 +6,13 @@
# Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018.
# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
# Anonymous <noreply@weblate.org>, 2020.
+# Lon3r <mptube.p@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-05-26 13:41+0000\n"
-"Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n"
+"PO-Revision-Date: 2020-08-28 13:09+0000\n"
+"Last-Translator: Lon3r <mptube.p@gmail.com>\n"
"Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/"
"th/>\n"
"Language: th\n"
@@ -19,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.1-dev\n"
+"X-Generator: Weblate 4.2.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -516,6 +517,7 @@ msgid "Seconds"
msgstr "วินาที"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "เฟรมเรท"
@@ -694,7 +696,7 @@ msgstr "ตรงตามอักษรพิมพ์เล็ก-ใหญ
msgid "Whole Words"
msgstr "ทั้งคำ"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "แทนที่"
@@ -744,9 +746,8 @@ msgid "Method in target node must be specified."
msgstr "ต้องระบุเมธอดในโหนดเป้าหมาย"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method name must be a valid identifier."
-msgstr "ไม่สามารถใช้ชื่อนี้ได้:"
+msgstr "ไม่สามารถใช้ชื่อนี้ได้."
#: editor/connections_dialog.cpp
msgid ""
@@ -884,6 +885,11 @@ msgid "Signals"
msgstr "สัญญาณ"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "ตัวกรองไทล์"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -921,7 +927,7 @@ msgid "Recent:"
msgstr "ล่าสุด:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "ค้นหา:"
@@ -1101,6 +1107,9 @@ msgstr "ผู้ริเริ่มโครงการ"
msgid "Lead Developer"
msgstr "ผู้พัฒนาหลัก"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "ผู้จัดการโครงการ "
@@ -1122,6 +1131,16 @@ msgid "Gold Sponsors"
msgstr "ผู้สนับสนุนระดับทอง"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "ผู้บริจาคระดับเงิน"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "ผู้บริจาคระดับทองแดง"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "ผู้สนับสนุน"
@@ -1438,7 +1457,7 @@ msgstr "จัดลำดับออโต้โหลด"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr ""
+msgstr "เพิ่มออโต้โหลดไม่ได้:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1596,20 +1615,20 @@ msgstr "แก้ไขผังฉาก"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "นำเข้า"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "โหมดเคลื่อนย้าย"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "ระบบไฟล์"
#: editor/editor_feature_profile.cpp
+#, fuzzy
+msgid "Import Dock"
+msgstr "นำเข้า"
+
+#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
msgstr "ลบโปรไฟล์ '%s' หรือไม่? (ทำกลับไม่ได้)"
@@ -1869,7 +1888,7 @@ msgstr "ไฟล์และโฟลเดอร์:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "ตัวอย่าง:"
@@ -2051,7 +2070,7 @@ msgstr "กำหนด"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "กำหนด หลายอย่าง:"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2103,19 +2122,21 @@ msgstr "โหนด"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "RPC กำลังมา"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "RSET กำลังมา"
#: editor/editor_network_profiler.cpp
+#, fuzzy
msgid "Outgoing RPC"
-msgstr ""
+msgstr "RPC กำลังออก"
#: editor/editor_network_profiler.cpp
+#, fuzzy
msgid "Outgoing RSET"
-msgstr ""
+msgstr "RSET กำลังออก"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
@@ -2719,22 +2740,28 @@ 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 "เมื่อส่งออก โปรแกรมจะพยายามเชื่อมต่อมายังคอมพิวเตอร์เครื่องนี้เพื่อทำการแก้ไขจุดบกพร่อง"
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
+msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "ส่งออกโดยใช้ระบบไฟล์เครือข่าย"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"ถ้าเปิดตัวเลือกนี้ ตัวเกมที่ส่งออกจะมีขนาดแค่พอใช้งานได้\n"
"ตัวเกมจะได้รับระบบไฟล์จากโปรแกรมแก้ไขผ่านเครือข่าย\n"
@@ -2745,9 +2772,10 @@ msgid "Visible Collision Shapes"
msgstr "ขอบเขตการชนที่มองเห็นได้"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr "รูปทรงกายภาพและรังสี (2D และ 3D) จะมองเห็นได้ขณะเริ่มโปรแกรมถ้าเปิดตัวเลือกนี้"
#: editor/editor_node.cpp
@@ -2755,35 +2783,40 @@ msgid "Visible Navigation"
msgstr "แสดงการนำทาง"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr "รูปทรงที่มีเส้นนำทางจะมองเห็นได้เมื่อเริ่มโปรแกรมถ้าเปิดตัวเลือกนี้"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "ซิงค์การเปลี่ยนแปลงฉาก"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"ถ้าเปิดตัวเลือกนี้ โปรแกรมที่รันอยู่จะได้รับการแก้ไขทันที\n"
"เมื่อใช้กับอุปกรณ์แบบรีโมท จะดีกว่าถ้าเปิดระบบไฟล์เครือข่ายด้วย"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "ซิงค์การเปลี่ยนแปลงสคริปต์"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"เมื่อเปิดตัวเลือกนี้ สคริปต์ที่บันทึกจะโหลดในเกมทันที\n"
"ถ้าใช้กับอุปกรณ์รีโมท จะดีกว่าถ้าเปิดระบบไฟล์เครือข่ายด้วย"
@@ -2845,7 +2878,7 @@ msgstr "ช่วยเหลือ"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "ค้นหา"
@@ -3246,9 +3279,11 @@ msgid "Add Key/Value Pair"
msgstr "เพิ่มคู่ของคีย์/ค่า"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"ไม่มีแม่แบบส่งออกที่สามารถรันเกมได้ของแพลตฟอร์มนี้\n"
"กรุณาเพิ่มแม่แบบส่งออกในเมนูส่งออก"
@@ -5011,7 +5046,7 @@ msgid "Bake Lightmaps"
msgstr "สร้าง Lightmaps"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "ตัวอย่าง"
@@ -7750,7 +7785,8 @@ msgid "New Animation"
msgstr "แอนิเมชันใหม่"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "ความเร็ว (เฟรม/วินาที):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9845,6 +9881,7 @@ msgstr ""
"ทำการสแกนหาโปรเจกต์ ในโฟลเดอร์ %s หรือไม่?\n"
"อาจจะใช้เวลาสักครู่"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "ตัวจัดการโปรเจกต์"
@@ -10285,11 +10322,18 @@ msgid "Batch Rename"
msgstr "เปลี่ยนชื่อ"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "แทนที่: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "คำนำหน้า"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "คำต่อท้าย"
#: editor/rename_dialog.cpp
@@ -10336,7 +10380,7 @@ msgid "Per-level Counter"
msgstr "ตัวนับต่อเลเวล"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10397,7 +10441,7 @@ msgstr "รีเซ็ตซูม"
#: editor/rename_dialog.cpp
#, fuzzy
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr "แก้ไขสมการ"
#: editor/rename_dialog.cpp
@@ -12414,6 +12458,11 @@ msgstr ""
"ไดรเวอร์วีดีโอ GLES2 ไม่สนับสนุน GIProbe\n"
"ใช้ BakedLightmap แทน"
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12696,6 +12745,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "ค่าคงที่ไม่สามารถแก้ไขได้"
+#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "ระบบไฟล์ และ นำเข้า"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "เมื่อส่งออก โปรแกรมจะพยายามเชื่อมต่อมายังคอมพิวเตอร์เครื่องนี้เพื่อทำการแก้ไขจุดบกพร่อง"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "ฉากปัจจุบันยังไม่ได้บันทึก กรุณาบันทึกก่อนเริ่มโปรแกรม"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index edc01421d2..c443d7bb94 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -50,12 +50,15 @@
# Vedat Günel <gunel15@itu.edu.tr>, 2020.
# Ahmet Elgün <ahmetelgn@gmail.com>, 2020.
# Efruz Yıldırır <efruzyildirir@gmail.com>, 2020.
+# Hazar <duurkak@yandex.com>, 2020.
+# Mutlu ORAN <mutlu.oran66@gmail.com>, 2020.
+# Yusuf Osman YILMAZ <wolfkan4219@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-06 04:41+0000\n"
-"Last-Translator: Efruz Yıldırır <efruzyildirir@gmail.com>\n"
+"PO-Revision-Date: 2020-09-15 07:17+0000\n"
+"Last-Translator: Yusuf Osman YILMAZ <wolfkan4219@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -63,7 +66,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -573,6 +576,7 @@ msgid "Seconds"
msgstr "Saniye"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -751,7 +755,7 @@ msgstr "Büyük/Küçük Harf Eşleştir"
msgid "Whole Words"
msgstr "Tam Kelimeler"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Değiştir"
@@ -943,6 +947,11 @@ msgid "Signals"
msgstr "Sinyaller"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Döşemelerde Bul"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Bu sinyalden, tüm bağlantıları kaldırmak istediğinizden emin misiniz?"
@@ -980,7 +989,7 @@ msgid "Recent:"
msgstr "Yakın zamanda:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Ara:"
@@ -1160,6 +1169,9 @@ msgstr "Projenin Kurucuları"
msgid "Lead Developer"
msgstr "Baş Geliştirici"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Proje Yöneticisi "
@@ -1181,6 +1193,16 @@ msgid "Gold Sponsors"
msgstr "Altın Sponsorlar"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Gümüş Bağışçılar"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Bronz Bağışçılar"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Mini Sponsorlar"
@@ -1657,16 +1679,17 @@ msgid "Scene Tree Editing"
msgstr "Sahne Ağacı Düzenleme"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Dock İçe Aktar"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Dock Nod"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "DosyaSistemi ve İçe Aktarım"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "DosyaSistemi"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Dock İçe Aktar"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1929,7 +1952,7 @@ msgstr "Dizinler & Dosyalar:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Önizleme:"
@@ -1976,7 +1999,7 @@ msgstr "Şundan miras alındı:"
#: editor/editor_help.cpp
msgid "Description"
-msgstr "Tanım"
+msgstr "Açıklama"
#: editor/editor_help.cpp
msgid "Online Tutorials"
@@ -1996,7 +2019,7 @@ msgstr "varsayılan:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr "Metotlar"
+msgstr "Yöntemler"
#: editor/editor_help.cpp
msgid "Theme Properties"
@@ -2027,8 +2050,9 @@ msgstr ""
"bulunarak[/url][/color] yardım edebilirsiniz!"
#: editor/editor_help.cpp
+#, fuzzy
msgid "Method Descriptions"
-msgstr "Metot Açıklamaları"
+msgstr "Yöntem Açıklamaları"
#: editor/editor_help.cpp
msgid ""
@@ -2805,24 +2829,28 @@ msgstr "Uzaktan Hata Ayıklama ile Dağıt"
#: 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Verilen yürütülebilir dosya, dışa aktarılırken veya dağıtıldığında, hata "
-"ayıklanacak şekilde bu bilgisayarın IP'sine bağlanmaya çalışacaktır."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Ağ DS ile Küçük Dağıtım"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Bu seçenek etkinleştirildiğinde, dışa aktarma veya dağıtma çok küçük bir "
"çalıştırılabilir dosya üretir.\n"
@@ -2835,9 +2863,10 @@ msgid "Visible Collision Shapes"
msgstr "Görünür Çarpışma Şekilleri"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Bu seçenek açıksa, çalışan oyunda çarpışma şekilleri ve raycast düğümleri "
"(2B ve 3B için) görünür olacaktır."
@@ -2847,23 +2876,26 @@ msgid "Visible Navigation"
msgstr "Görünür Yönlendirici"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Bu seçenek açıksa, çalışan oyunda yönlendirici örüntüleri ve çokgenler "
"görünür olacaktır."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Sahne Değişikliklerini Eş Zamanla"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Bu seçenek etkinleştirildiğinde, düzenleyicide bulunan sahnedeki "
"değişiklikler çalışmakta olan oyununda çoğaltılır.\n"
@@ -2871,15 +2903,17 @@ msgstr ""
"verimli olur."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Betik Değişikliklerini Eş Zamanla"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Bu seçenek etkinleştirildiğinde, kaydedilen tüm betik çalışan oyunda yeniden "
"yüklenecektir.\n"
@@ -2943,7 +2977,7 @@ msgstr "Yardım"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Ara"
@@ -3362,9 +3396,11 @@ msgid "Add Key/Value Pair"
msgstr "Anahtar/Değer İkilisini Ekle"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Çalıştırılabilir dışa aktarma önayarı bu platform için bulunamadı.\n"
"Lütfen dışa aktar menüsünden çalıştırılabilir bir önayar ekleyin."
@@ -5133,7 +5169,7 @@ msgid "Bake Lightmaps"
msgstr "Işık-Haritalarını Pişir"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Önizleme"
@@ -7431,6 +7467,11 @@ msgid ""
"Closed eye: Gizmo is hidden.\n"
"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")."
msgstr ""
+"Görünürlük ifadelerini değiştirmek için tıklayın.\n"
+"\n"
+"Açık göz: Gizmo görünür.\n"
+"Kapalı göz: Gizmo görünmez.\n"
+"Yarı-açık göz: Gizmo aynı zamanda saydam yüzeylerden görünür (\"x-ray\")."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
@@ -7770,7 +7811,8 @@ msgid "New Animation"
msgstr "Yeni Animasyon"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Hız (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9893,6 +9935,7 @@ msgstr ""
"misiniz?\n"
"Bu biraz zaman alabilir."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Proje Yöneticisi"
@@ -10332,11 +10375,18 @@ msgid "Batch Rename"
msgstr "Tümden Yeniden Adlandır"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Değiştir: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Ön Ek"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Son Ek"
#: editor/rename_dialog.cpp
@@ -10384,7 +10434,8 @@ msgid "Per-level Counter"
msgstr "Seviye Başına Sayaç"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Ayarlanmışsa, sayaç her bir alt düğüm grubu için yeniden başlar"
#: editor/rename_dialog.cpp
@@ -10444,7 +10495,8 @@ msgid "Reset"
msgstr "Sıfırla"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Düzenli İfade Hatası"
#: editor/rename_dialog.cpp
@@ -10516,9 +10568,8 @@ msgid "Instance Child Scene"
msgstr "Çocuk Sahnesini Örnekle"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach Script"
-msgstr "Betik İliştir"
+msgstr "Betiği Ayır"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
@@ -10555,7 +10606,6 @@ msgid "Make node as Root"
msgstr "Düğümü Kök düğüm yap"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
msgstr "\"%s\" düğümü ve alt düğümleri silinsin mi?"
@@ -10693,6 +10743,8 @@ msgid ""
"This is probably because this editor was built with all language modules "
"disabled."
msgstr ""
+"Bir yazı eklenemiyor: kayıtlı dil yok.\n"
+"Bu muhtemelen editor tüm dil modülleri kapalıyken kurulduğu için oldu."
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
@@ -10743,14 +10795,12 @@ msgstr ""
"alınmış bir sahne oluşturur."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Attach a new or existing script to the selected node."
-msgstr "Seçili düğüm için yeni veya mevcut bir betik iliştir."
+msgstr "Seçili düğüme yeni veya mevcut bir betik iliştir."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach the script from the selected node."
-msgstr "Seçilen düğüm için betik temizle."
+msgstr "Seçilen düğümden betiği ayır."
#: editor/scene_tree_dock.cpp
msgid "Remote"
@@ -12510,6 +12560,11 @@ msgstr ""
"GIProbes GLES2 video sürücüsü tarafından desteklenmez.\n"
"Bunun yerine bir BakedLightmap kullanın."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "90 dereceden geniş açılı SpotIşık gölge oluşturamaz."
@@ -12817,6 +12872,16 @@ msgstr "varyings yalnızca vertex işlevinde atanabilir."
msgid "Constants cannot be modified."
msgstr "Sabit değerler değiştirilemez."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "DosyaSistemi ve İçe Aktarım"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Verilen yürütülebilir dosya, dışa aktarılırken veya dağıtıldığında, hata "
+#~ "ayıklanacak şekilde bu bilgisayarın IP'sine bağlanmaya çalışacaktır."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Şimdiki sahne hiç kaydedilmedi, lütfen çalıştırmadan önce kaydediniz."
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index f7386bf72d..417c5aeeeb 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-04 06:43+0000\n"
+"PO-Revision-Date: 2020-09-05 09:37+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -29,7 +29,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -546,6 +546,7 @@ msgid "Seconds"
msgstr "Секунди"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "Кадри за секунду"
@@ -724,7 +725,7 @@ msgstr "Враховувати регістр"
msgid "Whole Words"
msgstr "Цілі слова"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Замінити"
@@ -917,6 +918,11 @@ msgid "Signals"
msgstr "Сигнали"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Фільтрувати плитки"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Ви справді хочете вилучити усі з'єднання з цього сигналу?"
@@ -954,7 +960,7 @@ msgid "Recent:"
msgstr "Нещодавні:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Пошук:"
@@ -1136,6 +1142,9 @@ msgstr "Засновники проєкту"
msgid "Lead Developer"
msgstr "Ведучий розробник"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Керівник проектів "
@@ -1157,6 +1166,14 @@ msgid "Gold Sponsors"
msgstr "Золоті спонсори"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Срібні донори"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Бронзові донори"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Міні-спонсори"
@@ -1633,16 +1650,17 @@ 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 "Бічна панель файлової системи та імпортування"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "Файлова система"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Бічна панель імпортування"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1906,7 +1924,7 @@ msgstr "Каталоги та файли:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Попередній перегляд:"
@@ -2787,24 +2805,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"При експорті або розгортанні, отриманий виконуваний файл буде намагатися "
-"підключитися до IP цього комп'ютера, для налагодження."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "Маленьке розгортання з Network File System"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Якщо цей параметр увімкнено, експорт або розгортання дають мінімальний "
"виконуваний файл.\n"
@@ -2817,9 +2839,10 @@ msgid "Visible Collision Shapes"
msgstr "Видимі контури зіткнень"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
"Контури зіткнення та вузли raycast (для 2D та 3D) буде видно в роботі гри, "
"якщо ця опція увімкнена."
@@ -2829,23 +2852,26 @@ msgid "Visible Navigation"
msgstr "Видимі навігації"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
"Навігаційні полісітки та полігони будуть видимі у запущеній грі, якщо ця "
"опція увімкнена."
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "Синхронізувати зміни сцени"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Якщо цей параметр увімкнено, будь-які зміни, внесені в сцену в редакторі, "
"будуть відтворені в роботі гри.\n"
@@ -2853,15 +2879,17 @@ msgstr ""
"файловою системою."
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "Синхронізувати зміни в скрипті"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"Якщо цей параметр увімкнено, будь-який скрипт, який буде збережений, буде "
"перезавантажений у поточній грі.\n"
@@ -2925,7 +2953,7 @@ msgstr "Довідка"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Пошук"
@@ -3344,9 +3372,11 @@ msgid "Add Key/Value Pair"
msgstr "Додати пару ключ-значення"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"Не знайдено робочий експортер для цієї платформи.\n"
"Будь ласка, додайте його в меню експорту."
@@ -5118,7 +5148,7 @@ msgid "Bake Lightmaps"
msgstr "Запікати карти освітлення"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Попередній перегляд"
@@ -7770,7 +7800,8 @@ msgid "New Animation"
msgstr "Нова анімація"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "Частота (кадри за сек.):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9902,6 +9933,7 @@ msgstr ""
"Ви справді хочете виконати пошук у %s теках наявних проєктів Godot?\n"
"Пошук може бути доволі тривалим."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Керівник проекту"
@@ -10341,11 +10373,18 @@ msgid "Batch Rename"
msgstr "Пакетне перейменування"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Замінити: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "Префікс"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "Суфікс"
#: editor/rename_dialog.cpp
@@ -10393,7 +10432,8 @@ msgid "Per-level Counter"
msgstr "Лічильник на рівень"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
"Якщо позначено, лічильник перезапускатиметься для кожної групи дочірніх "
"вузлів"
@@ -10455,7 +10495,8 @@ msgid "Reset"
msgstr "Скинути"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "Помилка у формальному виразі"
#: editor/rename_dialog.cpp
@@ -12554,6 +12595,11 @@ msgstr ""
"У драйвері GLES2 не передбачено підтримки GIProbes.\n"
"Скористайтеся замість них BakedLightmap."
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight з кутом, який є більшим за 90 градусів, не може давати тіні."
@@ -12863,6 +12909,16 @@ msgstr "Змінні величини можна пов'язувати лише
msgid "Constants cannot be modified."
msgstr "Сталі не можна змінювати."
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "Бічна панель файлової системи та імпортування"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "При експорті або розгортанні, отриманий виконуваний файл буде намагатися "
+#~ "підключитися до IP цього комп'ютера, для налагодження."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr ""
#~ "Поточна сцена ніколи не була збережена, будь ласка, збережіть її до "
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 4f4dccd8bb..2859b66ac9 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -516,6 +516,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -696,7 +697,7 @@ msgstr ""
msgid "Whole Words"
msgstr ""
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr ""
@@ -892,6 +893,11 @@ msgid "Signals"
msgstr ""
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -930,7 +936,7 @@ msgid "Recent:"
msgstr ""
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr ""
@@ -1104,6 +1110,9 @@ msgstr ""
msgid "Lead Developer"
msgstr ""
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr ""
@@ -1125,6 +1134,14 @@ msgid "Gold Sponsors"
msgstr ""
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr ""
@@ -1594,16 +1611,16 @@ msgid "Scene Tree Editing"
msgstr ""
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr ""
-
-#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Node Dock"
msgstr "ایکشن منتقل کریں"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
msgstr ""
#: editor/editor_feature_profile.cpp
@@ -1878,7 +1895,7 @@ msgstr ""
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr ""
@@ -2717,22 +2734,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2741,8 +2762,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2751,32 +2772,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2837,7 +2858,7 @@ msgstr ""
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr ""
@@ -3244,7 +3265,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5010,7 +5032,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -7662,7 +7684,7 @@ msgid "New Animation"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9703,6 +9725,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10139,11 +10162,15 @@ msgid "Batch Rename"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Prefix"
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10189,7 +10216,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10247,7 +10274,7 @@ msgid "Reset"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12230,6 +12257,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index bd52b850e4..2b56df15ed 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -534,6 +534,7 @@ msgid "Seconds"
msgstr "Giây"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -717,7 +718,7 @@ msgstr "Khớp Trường Hợp"
msgid "Whole Words"
msgstr "Cả từ"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "Thay thế"
@@ -911,6 +912,11 @@ msgid "Signals"
msgstr "Tín hiệu (Signal)"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "Lọc tệp tin ..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "Bạn có chắc muốn xóa bỏ tất cả kết nối từ tín hiệu này?"
@@ -948,7 +954,7 @@ msgid "Recent:"
msgstr "Gần đây:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "Tìm kiếm:"
@@ -1128,6 +1134,9 @@ msgstr "Các đồng sáng lập dự án"
msgid "Lead Developer"
msgstr "Phát triển chính"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "Quản lí Dự án "
@@ -1149,6 +1158,16 @@ msgid "Gold Sponsors"
msgstr "Nhà tài trợ Vàng"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "Người ủng hộ Bạc"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "Người ủng hộ Đồng"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "Nhà tài trợ Nhỏ"
@@ -1630,19 +1649,19 @@ msgid "Scene Tree Editing"
msgstr "Chỉnh sửa cảnh"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "Nhập vào"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "Nút"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "Hệ thống tập tin"
#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Nhập vào"
+
+#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
msgstr "Xoá hồ sơ '%s'? (không hoàn tác)"
@@ -1910,7 +1929,7 @@ msgstr "Các Thư mục và Tệp tin:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "Xem thử:"
@@ -2786,24 +2805,27 @@ msgstr "Triển khai gỡ lỗi từ xa"
#: editor/editor_node.cpp
msgid ""
-"When exporting or deploying, the resulting executable will attempt to "
-"connect to the IP of this computer in order to be debugged."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"Khi xuất ra hoặc triển khai, kết quả thực thi sẽ kết nối đến IP máy tính này "
-"để được gỡ lỗi."
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"Khi tuỳ chọn này được bật, lúc xuất hoặc triển khai sẽ tạo một tệp thực thi "
"tối giản nhất.\n"
@@ -2817,8 +2839,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2827,32 +2849,32 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2916,7 +2938,7 @@ msgstr "Trợ giúp"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "Tìm kiếm"
@@ -3334,7 +3356,8 @@ msgstr "Thêm cặp Khoá/Giá trị"
#: editor/editor_run_native.cpp
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5112,7 +5135,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "Xem thử"
@@ -7785,7 +7808,7 @@ msgid "New Animation"
msgstr "Tạo Animation mới"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9883,6 +9906,7 @@ msgstr ""
"Bạn có chắc chắn quét các thư mục %s để tìm các dự án Godot có sẵn?\n"
"Điều này sẽ mất chút thời gian."
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Trình quản lý Dự án"
@@ -10324,11 +10348,16 @@ msgid "Batch Rename"
msgstr "Đổi tên"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "Thay thế: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10375,7 +10404,8 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "Nếu đặt bộ đếm khởi động lại cho từng nhóm nút con"
#: editor/rename_dialog.cpp
@@ -10435,8 +10465,9 @@ msgid "Reset"
msgstr "Đặt lại phóng"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
-msgstr ""
+#, fuzzy
+msgid "Regular Expression Error:"
+msgstr "Phiên bản hiện tại:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12454,6 +12485,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12714,6 +12750,13 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Không thể chỉnh sửa hằng số."
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "Khi xuất ra hoặc triển khai, kết quả thực thi sẽ kết nối đến IP máy tính "
+#~ "này để được gỡ lỗi."
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "Cảnh hiện tại chưa được lưu, hãy lưu nó trước khi chạy."
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index f35da2476c..1fd689420b 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -70,12 +70,13 @@
# Silence Tai <silence.m@hotmail.com>, 2020.
# MintSoda <lionlxh@qq.com>, 2020.
# Gardner Belgrade <hapenia@sina.com>, 2020.
+# godhidden <z2zz2zz@yahoo.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
-"Last-Translator: Gardner Belgrade <hapenia@sina.com>\n"
+"PO-Revision-Date: 2020-09-24 12:43+0000\n"
+"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
"Language: zh_CN\n"
@@ -83,7 +84,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -584,6 +585,7 @@ msgid "Seconds"
msgstr "秒"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -762,7 +764,7 @@ msgstr "大小写匹配"
msgid "Whole Words"
msgstr "全字匹配"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "替换"
@@ -951,6 +953,11 @@ msgid "Signals"
msgstr "信号"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "筛选图块"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "你确定要从该广播信号中移除所有连接吗?"
@@ -988,7 +995,7 @@ msgid "Recent:"
msgstr "最近使用:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "搜索:"
@@ -1168,6 +1175,9 @@ msgstr "项目创始人"
msgid "Lead Developer"
msgstr "主要开发者"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "项目管理员 "
@@ -1189,6 +1199,14 @@ msgid "Gold Sponsors"
msgstr "黄金赞助"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "白银赞助"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "青铜赞助"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "迷你赞助"
@@ -1656,16 +1674,17 @@ 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 "文件系统和导入面板"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "文件系统"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "导入面板"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1927,7 +1946,7 @@ msgstr "目录与文件:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "预览:"
@@ -2779,23 +2798,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"导出或发布项目时,为了能够调试项目,可执行文件将试图通过本机IP连接到调试器。"
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "使用网络文件系统进行小型部署"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"当启用此项后,将在导出或发布项目时生成最小化可自行文件。\n"
"文件系统将通过网络连接到编辑器来实现。\n"
@@ -2806,9 +2830,10 @@ msgid "Visible Collision Shapes"
msgstr "显示碰撞区域"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr "如果启用此项,节点的碰撞区域和raycast将在游戏运行时可见。"
#: editor/editor_node.cpp
@@ -2816,35 +2841,40 @@ msgid "Visible Navigation"
msgstr "显示导航"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr "如果启用此项,用于导航的mesh和多边形将在游戏运行时可见。"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "同步场景修改"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"开启此项后,在编辑器中对场景的所有修改都会被应用与正在运行的游戏中。\n"
"当使用远程设备调试时,使用网络文件系统能有效提高编辑效率。"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "同步脚本变更"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"开启此项后,所有脚本在保存时都会被正在运行的游戏重新加载。\n"
"当使用远程设备调试时,使用网络文件系统能有效提高编辑效率。"
@@ -2906,7 +2936,7 @@ msgstr "帮助"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "搜索"
@@ -3116,7 +3146,7 @@ msgstr "找不到子资源。"
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr "创建网格预览"
+msgstr "正在创建网格预览"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
@@ -3315,9 +3345,11 @@ msgid "Add Key/Value Pair"
msgstr "添加键/值对"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"没有对应该平台的可执行导出预设。\n"
"请在导出菜单中添加可执行预设。"
@@ -5058,7 +5090,7 @@ msgid "Bake Lightmaps"
msgstr "烘焙光照贴图"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "预览"
@@ -5319,7 +5351,7 @@ msgstr "重置缩放"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
-msgstr "鼠标模式"
+msgstr "选择模式"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
@@ -7014,7 +7046,7 @@ msgstr "转到行..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr "设置断点"
+msgstr "切换断点"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
@@ -7402,7 +7434,7 @@ msgstr "插入动画帧"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
-msgstr "显示原点"
+msgstr "聚焦原点"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
@@ -7679,7 +7711,8 @@ msgid "New Animation"
msgstr "新建动画"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "速度(FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9402,7 +9435,7 @@ msgstr "包文件"
#: editor/project_export.cpp
msgid "Features"
-msgstr "功能"
+msgstr "特性"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9410,7 +9443,7 @@ msgstr "自定义 (以逗号分隔):"
#: editor/project_export.cpp
msgid "Feature List:"
-msgstr "功能列表:"
+msgstr "特性列表:"
#: editor/project_export.cpp
msgid "Script"
@@ -9748,6 +9781,7 @@ msgstr ""
"您确定要扫描%s文件夹中的现有Godot项目吗? \n"
"这可能需要一段时间。"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "项目管理器"
@@ -10183,11 +10217,18 @@ msgid "Batch Rename"
msgstr "批量重命名"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "替换: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "前缀"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "后缀"
#: editor/rename_dialog.cpp
@@ -10235,7 +10276,8 @@ msgid "Per-level Counter"
msgstr "各级单独计数"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "如果启用,计数器将为每组子节点重置"
#: editor/rename_dialog.cpp
@@ -10295,7 +10337,8 @@ msgid "Reset"
msgstr "重置"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "正则表达式出错"
#: editor/rename_dialog.cpp
@@ -10788,7 +10831,7 @@ msgstr "内置脚本(到场景文件中)。"
#: editor/script_create_dialog.cpp
msgid "Will create a new script file."
-msgstr "将创建一个新的脚本文件。"
+msgstr "将创建新脚本文件。"
#: editor/script_create_dialog.cpp
msgid "Will load an existing script file."
@@ -10838,7 +10881,7 @@ msgstr "错误:"
#: editor/script_editor_debugger.cpp
msgid "C++ Error"
-msgstr "C ++错误"
+msgstr "C++错误"
#: editor/script_editor_debugger.cpp
msgid "C++ Error:"
@@ -10846,7 +10889,7 @@ msgstr "C++错误:"
#: editor/script_editor_debugger.cpp
msgid "C++ Source"
-msgstr "C++源程序"
+msgstr "C++源文件"
#: editor/script_editor_debugger.cpp
msgid "Source:"
@@ -10854,7 +10897,7 @@ msgstr "源文件:"
#: editor/script_editor_debugger.cpp
msgid "C++ Source:"
-msgstr "C++源程序:"
+msgstr "C++源文件:"
#: editor/script_editor_debugger.cpp
msgid "Stack Trace"
@@ -10882,11 +10925,11 @@ msgstr "跳过断点"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
-msgstr "编辑上一个实例"
+msgstr "查看上一个实例"
#: editor/script_editor_debugger.cpp
msgid "Inspect Next Instance"
-msgstr "编辑下一个实例"
+msgstr "查看下一个实例"
#: editor/script_editor_debugger.cpp
msgid "Stack Frames"
@@ -10922,7 +10965,7 @@ msgstr "占用显存的资源列表:"
#: editor/script_editor_debugger.cpp
msgid "Total:"
-msgstr "合计:"
+msgstr "合计:"
#: editor/script_editor_debugger.cpp
msgid "Export list to a CSV file"
@@ -10970,15 +11013,15 @@ msgstr "导出为CSV格式"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
-msgstr "清除快捷方式"
+msgstr "清除快捷键"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
-msgstr "恢复快捷方式"
+msgstr "恢复快捷键"
#: editor/settings_config_dialog.cpp
msgid "Change Shortcut"
-msgstr "更改快捷方式"
+msgstr "更改快捷键"
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
@@ -11102,7 +11145,7 @@ msgstr "动态链接库"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr "启用gdnative singleton"
+msgstr "启用的 GDNative 单例"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Disabled GDNative Singleton"
@@ -11210,11 +11253,11 @@ msgstr "禁用裁剪"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clip Above"
-msgstr "裁剪上级"
+msgstr "向上裁剪"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clip Below"
-msgstr "裁剪下级"
+msgstr "向下裁剪"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Edit X Axis"
@@ -11302,7 +11345,7 @@ msgstr "清除导航网格(mesh)。"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
-msgstr "正在设置配置..。"
+msgstr "正在设置配置..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Calculating grid size..."
@@ -12287,6 +12330,11 @@ msgstr ""
"GLES2视频驱动程序不支持GIProbe。\n"
"请改用BakedLightmap。"
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "角度宽于 90 度的 SpotLight 无法投射出阴影。"
@@ -12570,6 +12618,16 @@ msgstr "变量只能在顶点函数中指定。"
msgid "Constants cannot be modified."
msgstr "不允许修改常量。"
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "文件系统和导入面板"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "导出或发布项目时,为了能够调试项目,可执行文件将试图通过本机IP连接到调试"
+#~ "器。"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "当前场景尚未保存,请保存后再尝试执行。"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index d4e1bf62dd..5ccf540635 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -549,6 +549,7 @@ msgid "Seconds"
msgstr ""
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr ""
@@ -742,7 +743,7 @@ msgstr "符合大小寫"
msgid "Whole Words"
msgstr "完整詞語"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
#, fuzzy
msgid "Replace"
msgstr "取代"
@@ -938,6 +939,11 @@ msgid "Signals"
msgstr "訊號"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "篩選檔案..."
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
@@ -980,7 +986,7 @@ msgid "Recent:"
msgstr "最近:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "搜尋:"
@@ -1158,6 +1164,9 @@ msgstr "專案開荒人"
msgid "Lead Developer"
msgstr "主要開發者"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "開啟 Project Manager "
@@ -1179,6 +1188,16 @@ msgid "Gold Sponsors"
msgstr "黃金級贊助人"
#: editor/editor_about.cpp
+#, fuzzy
+msgid "Silver Sponsors"
+msgstr "白銀級捐款人"
+
+#: editor/editor_about.cpp
+#, fuzzy
+msgid "Bronze Sponsors"
+msgstr "青銅級捐款人"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "迷你贊助人"
@@ -1673,21 +1692,21 @@ msgstr "即時編輯"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "Import Dock"
-msgstr "導入"
-
-#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
msgstr "移動模式"
#: editor/editor_feature_profile.cpp
#, fuzzy
-msgid "FileSystem and Import Docks"
+msgid "FileSystem Dock"
msgstr "檔案系統"
#: editor/editor_feature_profile.cpp
#, fuzzy
+msgid "Import Dock"
+msgstr "導入"
+
+#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Erase profile '%s'? (no undo)"
msgstr "全部取代"
@@ -1972,7 +1991,7 @@ msgstr "資料夾和檔案:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "預覽:"
@@ -2861,22 +2880,26 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+msgid "Small Deploy with Network Filesystem"
msgstr ""
#: editor/editor_node.cpp
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
#: editor/editor_node.cpp
@@ -2886,8 +2909,8 @@ 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."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr ""
#: editor/editor_node.cpp
@@ -2896,33 +2919,34 @@ msgstr ""
#: editor/editor_node.cpp
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Sync Scene Changes"
+msgid "Synchronize 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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize 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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
@@ -2990,7 +3014,7 @@ msgstr "幫助"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "搜尋"
@@ -3415,7 +3439,8 @@ 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."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
#: editor/editor_run_script.cpp
@@ -5292,7 +5317,7 @@ msgid "Bake Lightmaps"
msgstr ""
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr ""
@@ -8025,7 +8050,7 @@ msgid "New Animation"
msgstr "新的動畫名稱:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+msgid "Speed:"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -10130,6 +10155,7 @@ msgid ""
"This could take a while."
msgstr ""
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr ""
@@ -10583,11 +10609,16 @@ msgid "Batch Rename"
msgstr "重新命名..."
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "取代: "
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "Suffix"
+msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -10637,7 +10668,7 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
#: editor/rename_dialog.cpp
@@ -10698,7 +10729,7 @@ msgid "Reset"
msgstr "重設縮放比例"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+msgid "Regular Expression Error:"
msgstr ""
#: editor/rename_dialog.cpp
@@ -12752,6 +12783,11 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13010,6 +13046,10 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "檔案系統"
+
+#, fuzzy
#~ msgid "Not in resource path."
#~ msgstr "不在資源路徑。"
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 51efdfd2b8..4c693ce275 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -29,8 +29,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-31 03:47+0000\n"
-"Last-Translator: MintSoda <lionlxh@qq.com>\n"
+"PO-Revision-Date: 2020-09-08 11:40+0000\n"
+"Last-Translator: BinotaLIU <me@binota.org>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
@@ -38,7 +38,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.3-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -540,6 +540,7 @@ msgid "Seconds"
msgstr "秒"
#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
msgstr "FPS"
@@ -718,7 +719,7 @@ msgstr "區分大小寫"
msgid "Whole Words"
msgstr "搜尋完整單詞"
-#: editor/code_editor.cpp editor/rename_dialog.cpp
+#: editor/code_editor.cpp
msgid "Replace"
msgstr "取代"
@@ -907,6 +908,11 @@ msgid "Signals"
msgstr "訊號"
#: editor/connections_dialog.cpp
+#, fuzzy
+msgid "Filter signals"
+msgstr "篩選圖塊"
+
+#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
msgstr "確定要刪除所有來自此訊號的連接嗎?"
@@ -944,7 +950,7 @@ msgid "Recent:"
msgstr "最近存取:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
msgstr "搜尋:"
@@ -1124,6 +1130,9 @@ msgstr "專案創始人"
msgid "Lead Developer"
msgstr "主要開發者"
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
#: editor/editor_about.cpp
msgid "Project Manager "
msgstr "專案管理員 "
@@ -1145,6 +1154,14 @@ msgid "Gold Sponsors"
msgstr "黃金贊助"
#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "白銀贊助"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "青銅贊助"
+
+#: editor/editor_about.cpp
msgid "Mini Sponsors"
msgstr "迷你贊助"
@@ -1616,16 +1633,17 @@ msgid "Scene Tree Editing"
msgstr "正在編輯場景樹"
#: editor/editor_feature_profile.cpp
-msgid "Import Dock"
-msgstr "匯入 Dock"
-
-#: editor/editor_feature_profile.cpp
msgid "Node Dock"
msgstr "節點 Dock"
#: editor/editor_feature_profile.cpp
-msgid "FileSystem and Import Docks"
-msgstr "檔案系統與匯入 Dock"
+#, fuzzy
+msgid "FileSystem Dock"
+msgstr "檔案系統"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "匯入 Dock"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1887,7 +1905,7 @@ msgstr "資料夾與檔案:"
#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
#: editor/plugins/style_box_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview:"
msgstr "預覽:"
@@ -2737,23 +2755,28 @@ 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."
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
-"匯出或部署時,輸出的可執行檔將會嘗試連接到這台電腦的 IP 位置以進行除錯。"
#: editor/editor_node.cpp
-msgid "Small Deploy with Network FS"
+#, fuzzy
+msgid "Small Deploy with Network Filesystem"
msgstr "使用網路檔案系統進行小型部署"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"When this option is enabled, export or deploy will produce a minimal "
-"executable.\n"
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
"The filesystem will be provided from the project by the editor over the "
"network.\n"
-"On Android, deploy will use the USB cable for faster performance. This "
-"option speeds up testing for games with a large footprint."
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
msgstr ""
"啟用該選項後,匯出或部署是會產生最小可執行檔。\n"
"專案之檔案系統將由本編輯器以網路提供。\n"
@@ -2765,9 +2788,10 @@ msgid "Visible Collision Shapes"
msgstr "顯示碰撞區域"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
-"running game if this option is turned on."
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
msgstr "開啟選項後,執行遊戲時將可看見碰撞區域與(2D 或 3D 的)射線節點。"
#: editor/editor_node.cpp
@@ -2775,35 +2799,40 @@ msgid "Visible Navigation"
msgstr "顯示導航"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
-"Navigation meshes and polygons will be visible on the running game if this "
-"option is turned on."
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
msgstr "開啟該選項後,執行遊戲時將可看見導航網格 (mesh) 與多邊形。"
#: editor/editor_node.cpp
-msgid "Sync Scene Changes"
+#, fuzzy
+msgid "Synchronize Scene Changes"
msgstr "同步場景改動"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"開啟該選項後,編輯器中對該場景的所有改動都將被套用至執行中的遊戲。\n"
"若在遠端裝置上使用,可使用網路檔案系統 NFS 以獲得最佳效能。"
#: editor/editor_node.cpp
-msgid "Sync Script Changes"
+#, fuzzy
+msgid "Synchronize Script Changes"
msgstr "同步腳本改動"
#: editor/editor_node.cpp
+#, fuzzy
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."
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
msgstr ""
"開啟該選項後,保存之腳本都將於執行中的遊戲重新載入。\n"
"若在遠端裝置上使用,可使用網路檔案系統 NFS 以獲得最佳效能。"
@@ -2865,7 +2894,7 @@ msgstr "說明"
#: 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
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Search"
msgstr "搜尋"
@@ -3275,9 +3304,11 @@ msgid "Add Key/Value Pair"
msgstr "新增索引鍵/值組"
#: editor/editor_run_native.cpp
+#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
-"Please add a runnable preset in the export menu."
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
msgstr ""
"該平台沒有可執行的匯出預設設定。\n"
"請在匯出選單中新增一個可執行的預設設定。"
@@ -5019,7 +5050,7 @@ msgid "Bake Lightmaps"
msgstr "建立光照圖"
#: editor/plugins/camera_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
msgstr "預覽"
@@ -7640,7 +7671,8 @@ msgid "New Animation"
msgstr "新增動畫"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-msgid "Speed (FPS):"
+#, fuzzy
+msgid "Speed:"
msgstr "速度 (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -9710,6 +9742,7 @@ msgstr ""
"確定要掃描 %s 中的 Godot 專案嗎?\n"
"這可能需要一段時間。"
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "專案管理員"
@@ -10144,11 +10177,18 @@ msgid "Batch Rename"
msgstr "批次重新命名"
#: editor/rename_dialog.cpp
-msgid "Prefix"
+#, fuzzy
+msgid "Replace:"
+msgstr "取代: "
+
+#: editor/rename_dialog.cpp
+#, fuzzy
+msgid "Prefix:"
msgstr "前置"
#: editor/rename_dialog.cpp
-msgid "Suffix"
+#, fuzzy
+msgid "Suffix:"
msgstr "後置"
#: editor/rename_dialog.cpp
@@ -10196,7 +10236,8 @@ msgid "Per-level Counter"
msgstr "各級別分別計數器"
#: editor/rename_dialog.cpp
-msgid "If set the counter restarts for each group of child nodes"
+#, fuzzy
+msgid "If set, the counter restarts for each group of child nodes."
msgstr "若啟用則計數器將依據每組子節點重新啟動"
#: editor/rename_dialog.cpp
@@ -10256,7 +10297,8 @@ msgid "Reset"
msgstr "重設"
#: editor/rename_dialog.cpp
-msgid "Regular Expression Error"
+#, fuzzy
+msgid "Regular Expression Error:"
msgstr "正規表示式錯誤"
#: editor/rename_dialog.cpp
@@ -12258,6 +12300,11 @@ msgstr ""
"GLES2 視訊驅動程式不支援 GIProbs。\n"
"請改為使用 BakedLightmap。"
+#: scene/3d/interpolated_camera.cpp
+msgid ""
+"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+msgstr ""
+
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "角度大於 90 度的 SpotLight 無法投射出陰影。"
@@ -12547,6 +12594,15 @@ msgstr "Varying 變數只可在頂點函式中指派。"
msgid "Constants cannot be modified."
msgstr "不可修改常數。"
+#~ msgid "FileSystem and Import Docks"
+#~ msgstr "檔案系統與匯入 Dock"
+
+#~ msgid ""
+#~ "When exporting or deploying, the resulting executable will attempt to "
+#~ "connect to the IP of this computer in order to be debugged."
+#~ msgstr ""
+#~ "匯出或部署時,輸出的可執行檔將會嘗試連接到這台電腦的 IP 位置以進行除錯。"
+
#~ msgid "Current scene was never saved, please save it prior to running."
#~ msgstr "目前的場景從未被保存,請先保存以執行。"
diff --git a/glsl_builders.py b/glsl_builders.py
index af9afcae70..29971fd4e7 100644
--- a/glsl_builders.py
+++ b/glsl_builders.py
@@ -96,8 +96,6 @@ def build_rd_header(filename):
out_file = filename + ".gen.h"
fd = open(out_file, "w")
- enum_constants = []
-
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
out_file_base = out_file
@@ -165,7 +163,6 @@ class RAWHeaderStruct:
def include_file_in_raw_header(filename, header_data, depth):
fs = open(filename, "r")
line = fs.readline()
- text = ""
while line:
@@ -192,8 +189,6 @@ def build_raw_header(filename):
out_file = filename + ".gen.h"
fd = open(out_file, "w")
- enum_constants = []
-
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl")
@@ -211,11 +206,6 @@ def build_raw_header(filename):
fd.close()
-def build_rd_headers(target, source, env):
- for x in source:
- build_rd_header(str(x))
-
-
def build_raw_headers(target, source, env):
for x in source:
build_raw_header(str(x))
diff --git a/main/main.cpp b/main/main.cpp
index e45162c0f3..a2ea085618 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1274,9 +1274,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (rtm >= 0 && rtm < 3) {
+#ifdef NO_THREADS
+ rtm = OS::RENDER_THREAD_UNSAFE; // No threads available on this platform.
+#else
if (editor) {
rtm = OS::RENDER_THREAD_SAFE;
}
+#endif
OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm);
}
@@ -1565,7 +1569,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Color boot_bg_color = GLOBAL_DEF("application/boot_splash/bg_color", boot_splash_bg_color);
if (boot_logo.is_valid()) {
- OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec();
RenderingServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale,
boot_logo_filter);
@@ -1805,7 +1808,6 @@ bool Main::start() {
}
}
- String main_loop_type;
#ifdef TOOLS_ENABLED
if (doc_tool != "") {
Engine::get_singleton()->set_editor_hint(
@@ -1900,6 +1902,7 @@ bool Main::start() {
if (editor) {
main_loop = memnew(SceneTree);
};
+ String main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "SceneTree");
if (script != "") {
Ref<Script> script_res = ResourceLoader::load(script);
@@ -1930,9 +1933,23 @@ bool Main::start() {
} else {
return false;
}
-
- } else {
- main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "");
+ } else { // Not based on script path.
+ if (!editor && !ClassDB::class_exists(main_loop_type) && ScriptServer::is_global_class(main_loop_type)) {
+ String script_path = ScriptServer::get_global_class_path(main_loop_type);
+ Ref<Script> script_res = ResourceLoader::load(script_path);
+ StringName script_base = ScriptServer::get_global_class_native_base(main_loop_type);
+ Object *obj = ClassDB::instance(script_base);
+ MainLoop *script_loop = Object::cast_to<MainLoop>(obj);
+ if (!script_loop) {
+ if (obj) {
+ memdelete(obj);
+ }
+ DisplayServer::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base);
+ ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type));
+ }
+ script_loop->set_init_script(script_res);
+ main_loop = script_loop;
+ }
}
if (!main_loop && main_loop_type == "") {
@@ -2278,6 +2295,13 @@ bool Main::start() {
}
if (project_manager || editor) {
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CONSOLE_WINDOW)) {
+ // Hide console window if requested (Windows-only).
+ bool hide_console = EditorSettings::get_singleton()->get_setting(
+ "interface/editor/hide_console_window");
+ DisplayServer::get_singleton()->console_set_visible(!hide_console);
+ }
+
// Load SSL Certificates from Editor Settings (or builtin)
Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting(
"network/ssl/editor_ssl_certificates")
diff --git a/main/main_builders.py b/main/main_builders.py
index 2ea774e3b4..aa91201c3e 100644
--- a/main/main_builders.py
+++ b/main/main_builders.py
@@ -4,7 +4,6 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
"""
from platform_methods import subprocess_main
-from collections import OrderedDict
def make_splash(target, source, env):
diff --git a/main/splash_editor.png b/main/splash_editor.png
index 29931a71db..855646b346 100644
--- a/main/splash_editor.png
+++ b/main/splash_editor.png
Binary files differ
diff --git a/methods.py b/methods.py
index 44e381014d..f7134b472b 100644
--- a/methods.py
+++ b/methods.py
@@ -7,6 +7,8 @@ from collections import OrderedDict
# We need to define our own `Action` method to control the verbosity of output
# and whenever we need to run those commands in a subprocess on some platforms.
from SCons.Script import Action
+from SCons import Node
+from SCons.Script import Glob
from platform_methods import run_in_subprocess
@@ -185,7 +187,7 @@ def write_modules(module_list):
unregister_cpp += "#ifdef MODULE_" + name.upper() + "_ENABLED\n"
unregister_cpp += "\tunregister_" + name + "_types();\n"
unregister_cpp += "#endif\n"
- except IOError:
+ except OSError:
pass
modules_cpp = """// register_module_types.gen.cpp
@@ -522,10 +524,39 @@ def generate_cpp_hint_file(filename):
try:
with open(filename, "w") as fd:
fd.write("#define GDCLASS(m_class, m_inherits)\n")
- except IOError:
+ except OSError:
print("Could not write cpp.hint file.")
+def glob_recursive(pattern, node="."):
+ results = []
+ for f in Glob(str(node) + "/*", source=True):
+ if type(f) is Node.FS.Dir:
+ results += glob_recursive(pattern, f)
+ results += Glob(str(node) + "/" + pattern, source=True)
+ return results
+
+
+def add_to_vs_project(env, sources):
+ for x in sources:
+ if type(x) == type(""):
+ fname = env.File(x).path
+ else:
+ fname = env.File(x)[0].path
+ pieces = fname.split(".")
+ if len(pieces) > 0:
+ basename = pieces[0]
+ basename = basename.replace("\\\\", "/")
+ if os.path.isfile(basename + ".h"):
+ env.vs_incs += [basename + ".h"]
+ elif os.path.isfile(basename + ".hpp"):
+ env.vs_incs += [basename + ".hpp"]
+ if os.path.isfile(basename + ".c"):
+ env.vs_srcs += [basename + ".c"]
+ elif os.path.isfile(basename + ".cpp"):
+ env.vs_srcs += [basename + ".cpp"]
+
+
def generate_vs_project(env, num_jobs):
batch_file = find_visual_c_batch_file(env)
if batch_file:
@@ -534,37 +565,44 @@ def generate_vs_project(env, num_jobs):
common_build_prefix = [
'cmd /V /C set "plat=$(PlatformTarget)"',
'(if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64"))',
- 'set "tools=yes"',
+ 'set "tools=%s"' % env["tools"],
'(if "$(Configuration)"=="release" (set "tools=no"))',
'call "' + batch_file + '" !plat!',
]
- result = " ^& ".join(common_build_prefix + [commands])
+ # windows allows us to have spaces in paths, so we need
+ # to double quote off the directory. However, the path ends
+ # in a backslash, so we need to remove this, lest it escape the
+ # last double quote off, confusing MSBuild
+ common_build_postfix = [
+ "--directory=\"$(ProjectDir.TrimEnd('\\'))\"",
+ "platform=windows",
+ "target=$(Configuration)",
+ "progress=no",
+ "tools=!tools!",
+ "-j%s" % num_jobs,
+ ]
+
+ if env["custom_modules"]:
+ common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
+
+ result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
return result
- env.AddToVSProject(env.core_sources)
- env.AddToVSProject(env.main_sources)
- env.AddToVSProject(env.modules_sources)
- env.AddToVSProject(env.scene_sources)
- env.AddToVSProject(env.servers_sources)
- env.AddToVSProject(env.editor_sources)
-
- # windows allows us to have spaces in paths, so we need
- # to double quote off the directory. However, the path ends
- # in a backslash, so we need to remove this, lest it escape the
- # last double quote off, confusing MSBuild
- env["MSVSBUILDCOM"] = build_commandline(
- "scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" platform=windows progress=no target=$(Configuration)"
- " tools=!tools! -j" + str(num_jobs)
- )
- env["MSVSREBUILDCOM"] = build_commandline(
- "scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" platform=windows progress=no target=$(Configuration)"
- " tools=!tools! vsproj=yes -j" + str(num_jobs)
- )
- env["MSVSCLEANCOM"] = build_commandline(
- "scons --directory=\"$(ProjectDir.TrimEnd('\\'))\" --clean platform=windows progress=no"
- " target=$(Configuration) tools=!tools! -j" + str(num_jobs)
- )
+ add_to_vs_project(env, env.core_sources)
+ add_to_vs_project(env, env.drivers_sources)
+ add_to_vs_project(env, env.main_sources)
+ add_to_vs_project(env, env.modules_sources)
+ add_to_vs_project(env, env.scene_sources)
+ add_to_vs_project(env, env.servers_sources)
+ add_to_vs_project(env, env.editor_sources)
+
+ for header in glob_recursive("**/*.h"):
+ env.vs_incs.append(str(header))
+
+ env["MSVSBUILDCOM"] = build_commandline("scons")
+ env["MSVSREBUILDCOM"] = build_commandline("scons vsproj=yes")
+ env["MSVSCLEANCOM"] = build_commandline("scons --clean")
# This version information (Win32, x64, Debug, Release, Release_Debug seems to be
# required for Visual Studio to understand that it needs to generate an NMAKE
diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html
index a5633115d5..85064b34fd 100644
--- a/misc/dist/html/fixed-size.html
+++ b/misc/dist/html/fixed-size.html
@@ -236,7 +236,6 @@ $GODOT_HEAD_INCLUDE
const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED;
const INDETERMINATE_STATUS_STEP_MS = 100;
- var container = document.getElementById('container');
var canvas = document.getElementById('canvas');
var statusProgress = document.getElementById('status-progress');
var statusProgressInner = document.getElementById('status-progress-inner');
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 435013cb5e..58cf8ba4d8 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -147,6 +147,7 @@ $GODOT_HEAD_INCLUDE
const MAIN_PACK = '$GODOT_BASENAME.pck';
const EXTRA_ARGS = JSON.parse('$GODOT_ARGS');
const INDETERMINATE_STATUS_STEP_MS = 100;
+ const FULL_WINDOW = $GODOT_FULL_WINDOW;
var canvas = document.getElementById('canvas');
var statusProgress = document.getElementById('status-progress');
@@ -156,6 +157,9 @@ $GODOT_HEAD_INCLUDE
var initializing = true;
var statusMode = 'hidden';
+ var lastWidth = 0;
+ var lastHeight = 0;
+ var lastScale = 0;
var animationCallbacks = [];
function animate(time) {
@@ -165,14 +169,23 @@ $GODOT_HEAD_INCLUDE
requestAnimationFrame(animate);
function adjustCanvasDimensions() {
- var scale = window.devicePixelRatio || 1;
- var width = window.innerWidth;
- var height = window.innerHeight;
- canvas.width = width * scale;
- canvas.height = height * scale;
+ const scale = window.devicePixelRatio || 1;
+ if (lastWidth != window.innerWidth || lastHeight != window.innerHeight || lastScale != scale) {
+ lastScale = scale;
+ lastWidth = window.innerWidth;
+ lastHeight = window.innerHeight;
+ canvas.width = Math.floor(lastWidth * scale);
+ canvas.height = Math.floor(lastHeight * scale);
+ canvas.style.width = lastWidth + "px";
+ canvas.style.height = lastHeight + "px";
+ }
+ }
+ if (FULL_WINDOW) {
+ animationCallbacks.push(adjustCanvasDimensions);
+ adjustCanvasDimensions();
+ } else {
+ engine.setCanvasResizedOnStart(true);
}
- animationCallbacks.push(adjustCanvasDimensions);
- adjustCanvasDimensions();
setStatusMode = function setStatusMode(mode) {
@@ -201,7 +214,7 @@ $GODOT_HEAD_INCLUDE
throw new Error('Invalid status mode');
}
statusMode = mode;
- }
+ };
function animateStatusIndeterminate(ms) {
diff --git a/modules/arkit/register_types.h b/modules/arkit/register_types.h
index 5c697baf68..f8939a1e3f 100644
--- a/modules/arkit/register_types.h
+++ b/modules/arkit/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef ARKIT_REGISTER_TYPES_H
+#define ARKIT_REGISTER_TYPES_H
+
void register_arkit_types();
void unregister_arkit_types();
+
+#endif // ARKIT_REGISTER_TYPES_H
diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h
index 8de151ede0..20ecf15a59 100644
--- a/modules/basis_universal/texture_basisu.h
+++ b/modules/basis_universal/texture_basisu.h
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef BASIS_UNIVERSAL_TEXTURE_BASISU_H
+#define BASIS_UNIVERSAL_TEXTURE_BASISU_H
+
#include "scene/resources/texture.h"
#ifdef TOOLS_ENABLED
@@ -75,3 +78,5 @@ public:
};
#endif
+
+#endif // BASIS_UNIVERSAL_TEXTURE_BASISU_H
diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp
index c9493d8892..7ecad9b78a 100644
--- a/modules/bullet/bullet_types_converter.cpp
+++ b/modules/bullet/bullet_types_converter.cpp
@@ -95,12 +95,61 @@ void G_TO_B(Transform const &inVal, btTransform &outVal) {
}
void UNSCALE_BT_BASIS(btTransform &scaledBasis) {
- btMatrix3x3 &m(scaledBasis.getBasis());
- btVector3 column0(m[0][0], m[1][0], m[2][0]);
- btVector3 column1(m[0][1], m[1][1], m[2][1]);
- btVector3 column2(m[0][2], m[1][2], m[2][2]);
+ btMatrix3x3 &basis(scaledBasis.getBasis());
+ btVector3 column0 = basis.getColumn(0);
+ btVector3 column1 = basis.getColumn(1);
+ btVector3 column2 = basis.getColumn(2);
+
+ // Check for zero scaling.
+ if (btFuzzyZero(column0[0])) {
+ if (btFuzzyZero(column1[1])) {
+ if (btFuzzyZero(column2[2])) {
+ // All dimensions are fuzzy zero. Create a default basis.
+ column0 = btVector3(1, 0, 0);
+ column1 = btVector3(0, 1, 0);
+ column2 = btVector3(0, 0, 1);
+ } else { // Column 2 scale not fuzzy zero.
+ // Create two vectors orthogonal to row 2.
+ // Ensure that a default basis is created if row 2 = <0, 0, 1>
+ column1 = btVector3(0, column2[2], -column2[1]);
+ column0 = column1.cross(column2);
+ }
+ } else { // Column 1 scale not fuzzy zero.
+ if (btFuzzyZero(column2[2])) {
+ // Create two vectors othogonal to column 1.
+ // Ensure that a default basis is created if column 1 = <0, 1, 0>
+ column0 = btVector3(column1[1], -column1[0], 0);
+ column2 = column0.cross(column1);
+ } else { // Column 1 and column 2 scales not fuzzy zero.
+ // Create column 0 orthogonal to column 1 and column 2.
+ column0 = column1.cross(column2);
+ }
+ }
+ } else { // Column 0 scale not fuzzy zero.
+ if (btFuzzyZero(column1[1])) {
+ if (btFuzzyZero(column2[2])) {
+ // Create two vectors orthogonal to column 0.
+ // Ensure that a default basis is created if column 0 = <1, 0, 0>
+ column2 = btVector3(-column0[2], 0, column0[0]);
+ column1 = column2.cross(column0);
+ } else { // Column 0 and column 2 scales not fuzzy zero.
+ // Create column 1 orthogonal to column 0 and column 2.
+ column1 = column2.cross(column0);
+ }
+ } else { // Column 0 and column 1 scales not fuzzy zero.
+ if (btFuzzyZero(column2[2])) {
+ // Create column 2 orthogonal to column 0 and column 1.
+ column2 = column0.cross(column1);
+ }
+ }
+ }
+
+ // Normalize
column0.normalize();
column1.normalize();
column2.normalize();
- m.setValue(column0[0], column1[0], column2[0], column0[1], column1[1], column2[1], column0[2], column1[2], column2[2]);
+
+ basis.setValue(column0[0], column1[0], column2[0],
+ column0[1], column1[1], column2[1],
+ column0[2], column1[2], column2[2]);
}
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 32c3240a35..f517eecf64 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -849,8 +849,8 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
} else {
if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) {
// The position was found, just shift all elements
- for (int j = i; j < areaWhereIamCount; ++j) {
- areasWhereIam[j + 1] = areasWhereIam[j];
+ for (int j = areaWhereIamCount; j > i; j--) {
+ areasWhereIam[j] = areasWhereIam[j - 1];
}
areasWhereIam[i] = p_area;
break;
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 274493ed17..74d6e073b3 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -308,7 +308,7 @@ void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) {
}
btCollisionShape *CapsuleShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
- return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1] + p_extra_edge));
+ return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1]));
}
/* Cylinder */
diff --git a/modules/camera/register_types.h b/modules/camera/register_types.h
index f2753cb6d7..e34f84bf2c 100644
--- a/modules/camera/register_types.h
+++ b/modules/camera/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef CAMERA_REGISTER_TYPES_H
+#define CAMERA_REGISTER_TYPES_H
+
void register_camera_types();
void unregister_camera_types();
+
+#endif // CAMERA_REGISTER_TYPES_H
diff --git a/modules/csg/doc_classes/CSGShape3D.xml b/modules/csg/doc_classes/CSGShape3D.xml
index 43ce988c30..dac556c7f1 100644
--- a/modules/csg/doc_classes/CSGShape3D.xml
+++ b/modules/csg/doc_classes/CSGShape3D.xml
@@ -71,10 +71,10 @@
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this area is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property.
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this CSG shape scans for collisions.
+ The physics layers this CSG shape scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape3D.Operation" default="0">
The operation that is performed on this shape. This is ignored for the first CSG child node as the operation is between this node and the previous child of this nodes parent.
diff --git a/modules/cvtt/register_types.h b/modules/cvtt/register_types.h
index 8472980c6a..36b5e332d6 100644
--- a/modules/cvtt/register_types.h
+++ b/modules/cvtt/register_types.h
@@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef TOOLS_ENABLED
-
#ifndef CVTT_REGISTER_TYPES_H
#define CVTT_REGISTER_TYPES_H
+#ifdef TOOLS_ENABLED
+
void register_cvtt_types();
void unregister_cvtt_types();
-#endif // CVTT_REGISTER_TYPES_H
-
#endif // TOOLS_ENABLED
+
+#endif // CVTT_REGISTER_TYPES_H
diff --git a/modules/denoise/register_types.h b/modules/denoise/register_types.h
index 2ffc36ee2c..f0f1f44bfe 100644
--- a/modules/denoise/register_types.h
+++ b/modules/denoise/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef DENOISE_REGISTER_TYPES_H
+#define DENOISE_REGISTER_TYPES_H
+
void register_denoise_types();
void unregister_denoise_types();
+
+#endif // DENOISE_REGISTER_TYPES_H
diff --git a/modules/denoise/resource_to_cpp.py b/modules/denoise/resource_to_cpp.py
index 4c0b67f701..6c83277355 100644
--- a/modules/denoise/resource_to_cpp.py
+++ b/modules/denoise/resource_to_cpp.py
@@ -17,8 +17,6 @@
## ======================================================================== ##
import os
-import sys
-import argparse
from array import array
# Generates a C++ file from the specified binary resource file
diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
index c908af7479..f46ef2d812 100644
--- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
+++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
@@ -7,8 +7,8 @@
A PacketPeer implementation that should be passed to [member SceneTree.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
- <link>http://enet.bespin.org/usergroup0.html</link>
+ <link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
+ <link title="API documentation on the ENet website">http://enet.bespin.org/usergroup0.html</link>
</tutorials>
<methods>
<method name="close_connection">
diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml
index 1aab864102..05cda05f9f 100644
--- a/modules/gdnative/doc_classes/GDNativeLibrary.xml
+++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml
@@ -7,8 +7,8 @@
A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [XRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link>
- <link>https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-cpp-example.html</link>
+ <link title="GDNative C example">https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link>
+ <link title="GDNative C++ example">https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-cpp-example.html</link>
</tutorials>
<methods>
<method name="get_current_dependencies" qualifiers="const">
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 26c40b625c..1fa19f4ff5 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -40,9 +40,10 @@
extern "C" {
#endif
+static_assert(sizeof(godot_char16_string) == sizeof(Char16String), "Char16String size mismatch");
static_assert(sizeof(godot_char_string) == sizeof(CharString), "CharString size mismatch");
static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch");
-static_assert(sizeof(godot_char_type) == sizeof(CharType), "CharType size mismatch");
+static_assert(sizeof(godot_char_type) == sizeof(char32_t), "char32_t size mismatch");
godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs) {
const CharString *cs = (const CharString *)p_cs;
@@ -62,6 +63,24 @@ void GDAPI godot_char_string_destroy(godot_char_string *p_cs) {
cs->~CharString();
}
+godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs) {
+ const Char16String *cs = (const Char16String *)p_cs;
+
+ return cs->length();
+}
+
+const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs) {
+ const Char16String *cs = (const Char16String *)p_cs;
+
+ return cs->get_data();
+}
+
+void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs) {
+ Char16String *cs = (Char16String *)p_cs;
+
+ cs->~Char16String();
+}
+
void GDAPI godot_string_new(godot_string *r_dest) {
String *dest = (String *)r_dest;
memnew_placement(dest, String);
@@ -70,27 +89,97 @@ void GDAPI godot_string_new(godot_string *r_dest) {
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src) {
String *dest = (String *)r_dest;
const String *src = (const String *)p_src;
- memnew_placement(dest, String(*src));
+ memnew_placement(dest, String);
+ *dest = String(*src);
+}
+
+void GDAPI godot_string_new_with_latin1_chars(godot_string *r_dest, const char *p_contents) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ *dest = String(p_contents);
+}
+
+void GDAPI godot_string_new_with_utf8_chars(godot_string *r_dest, const char *p_contents) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ dest->parse_utf8(p_contents);
+}
+
+void GDAPI godot_string_new_with_utf16_chars(godot_string *r_dest, const char16_t *p_contents) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ dest->parse_utf16(p_contents);
+}
+
+void GDAPI godot_string_new_with_utf32_chars(godot_string *r_dest, const char32_t *p_contents) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ *dest = String((const char32_t *)p_contents);
+}
+
+void GDAPI godot_string_new_with_wide_chars(godot_string *r_dest, const wchar_t *p_contents) {
+ String *dest = (String *)r_dest;
+ if (sizeof(wchar_t) == 2) {
+ // wchar_t is 16 bit, parse.
+ memnew_placement(dest, String);
+ dest->parse_utf16((const char16_t *)p_contents);
+ } else {
+ // wchar_t is 32 bit, copy.
+ memnew_placement(dest, String);
+ *dest = String((const char32_t *)p_contents);
+ }
+}
+
+void GDAPI godot_string_new_with_latin1_chars_and_len(godot_string *r_dest, const char *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ *dest = String(p_contents, p_size);
+}
+
+void GDAPI godot_string_new_with_utf8_chars_and_len(godot_string *r_dest, const char *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ dest->parse_utf8(p_contents, p_size);
+}
+
+void GDAPI godot_string_new_with_utf16_chars_and_len(godot_string *r_dest, const char16_t *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ dest->parse_utf16(p_contents, p_size);
+}
+
+void GDAPI godot_string_new_with_utf32_chars_and_len(godot_string *r_dest, const char32_t *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
+ *dest = String((const char32_t *)p_contents, p_size);
}
-void GDAPI godot_string_new_with_wide_string(godot_string *r_dest, const wchar_t *p_contents, const int p_size) {
+void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const wchar_t *p_contents, const int p_size) {
String *dest = (String *)r_dest;
- memnew_placement(dest, String(p_contents, p_size));
+ if (sizeof(wchar_t) == 2) {
+ // wchar_t is 16 bit, parse.
+ memnew_placement(dest, String);
+ dest->parse_utf16((const char16_t *)p_contents, p_size);
+ } else {
+ // wchar_t is 32 bit, copy.
+ memnew_placement(dest, String);
+ *dest = String((const char32_t *)p_contents, p_size);
+ }
}
-const wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) {
+const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) {
String *self = (String *)p_self;
return &(self->operator[](p_idx));
}
-wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx) {
+godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx) {
const String *self = (const String *)p_self;
return self->operator[](p_idx);
}
-const wchar_t GDAPI *godot_string_wide_str(const godot_string *p_self) {
+const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self) {
const String *self = (const String *)p_self;
- return self->c_str();
+ return self->get_data();
}
godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b) {
@@ -162,22 +251,14 @@ godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self,
return self->begins_with(p_char_array);
}
-godot_array GDAPI godot_string_bigrams(const godot_string *p_self) {
+godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self) {
const String *self = (const String *)p_self;
- Vector<String> return_value = self->bigrams();
-
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
-
- return result;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->bigrams()));
+ return ret;
};
-godot_string GDAPI godot_string_chr(wchar_t p_character) {
+godot_string GDAPI godot_string_chr(godot_char_type p_character) {
godot_string result;
memnew_placement(&result, String(String::chr(p_character)));
@@ -191,88 +272,73 @@ 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) {
+godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+
+ return self->ends_with(p_char_array);
+}
+
+godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ const String *what = (const String *)p_what;
return self->count(*what, p_from, p_to);
}
-godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->countn(*what, p_from, p_to);
}
-godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what) {
+godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->find(*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_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->find(*what, p_from);
}
-godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys) {
+godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys) {
const String *self = (const String *)p_self;
-
- Vector<String> keys;
- Array *keys_proxy = (Array *)p_keys;
- keys.resize(keys_proxy->size());
- for (int i = 0; i < keys_proxy->size(); i++) {
- keys.write[i] = (*keys_proxy)[i];
- }
-
- return self->findmk(keys);
+ const Vector<String> *keys = (const Vector<String> *)p_keys;
+ return self->findmk(*keys);
}
-godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_array *p_keys, godot_int p_from) {
+godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from) {
const String *self = (const String *)p_self;
-
- Vector<String> keys;
- Array *keys_proxy = (Array *)p_keys;
- keys.resize(keys_proxy->size());
- for (int i = 0; i < keys_proxy->size(); i++) {
- keys.write[i] = (*keys_proxy)[i];
- }
-
- return self->findmk(keys, p_from);
+ const Vector<String> *keys = (const Vector<String> *)p_keys;
+ return self->findmk(*keys, p_from);
}
-godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key) {
+godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key) {
const String *self = (const String *)p_self;
-
- Vector<String> keys;
- Array *keys_proxy = (Array *)p_keys;
- keys.resize(keys_proxy->size());
- for (int i = 0; i < keys_proxy->size(); i++) {
- keys.write[i] = (*keys_proxy)[i];
- }
-
+ const Vector<String> *keys = (const Vector<String> *)p_keys;
int key;
- int ret = self->findmk(keys, p_from, &key);
+ int ret = self->findmk(*keys, p_from, &key);
if (r_key) {
*r_key = key;
}
return ret;
}
-godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what) {
+godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->findn(*what);
}
-godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from) {
+godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->findn(*what, p_from);
}
@@ -303,21 +369,9 @@ godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot
return result;
}
-godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hex_to_int();
-}
-
-godot_int GDAPI godot_string_hex_to_int_without_prefix(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hex_to_int(true);
-}
-
-godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, godot_string p_string) {
+godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string) {
const String *self = (const String *)p_self;
- String *content = (String *)&p_string;
+ const String *content = (const String *)p_string;
godot_string result;
memnew_placement(&result, String(self->insert(p_at_pos, *content)));
@@ -440,58 +494,58 @@ godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int
return result;
}
-godot_string GDAPI godot_string_replace(const godot_string *p_self, godot_string p_key, godot_string p_with) {
+godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
const String *self = (const String *)p_self;
- String *key = (String *)&p_key;
- String *with = (String *)&p_with;
+ const String *key = (const String *)p_key;
+ const String *with = (const String *)p_with;
godot_string result;
memnew_placement(&result, String(self->replace(*key, *with)));
return result;
}
-godot_string GDAPI godot_string_replacen(const godot_string *p_self, godot_string p_key, godot_string p_with) {
+godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
const String *self = (const String *)p_self;
- String *key = (String *)&p_key;
- String *with = (String *)&p_with;
+ const String *key = (const String *)p_key;
+ const String *with = (const String *)p_with;
godot_string result;
memnew_placement(&result, String(self->replacen(*key, *with)));
return result;
}
-godot_int GDAPI godot_string_rfind(const godot_string *p_self, godot_string p_what) {
+godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->rfind(*what);
}
-godot_int GDAPI godot_string_rfindn(const godot_string *p_self, godot_string p_what) {
+godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->rfindn(*what);
}
-godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, godot_string p_what, godot_int p_from) {
+godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->rfind(*what, p_from);
}
-godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, godot_string p_what, godot_int p_from) {
+godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
const String *self = (const String *)p_self;
- String *what = (String *)&p_what;
+ const String *what = (const String *)p_what;
return self->rfindn(*what, p_from);
}
-godot_string GDAPI godot_string_replace_first(const godot_string *p_self, godot_string p_key, godot_string p_with) {
+godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
const String *self = (const String *)p_self;
- String *key = (String *)&p_key;
- String *with = (String *)&p_with;
+ const String *key = (const String *)p_key;
+ const String *with = (const String *)p_with;
godot_string result;
memnew_placement(&result, String(self->replace_first(*key, *with)));
@@ -541,16 +595,16 @@ godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_f
return result;
}
-double GDAPI godot_string_to_float(const godot_string *p_self) {
+godot_int GDAPI godot_string_to_int(const godot_string *p_self) {
const String *self = (const String *)p_self;
- return self->to_float();
+ return self->to_int();
}
-godot_int GDAPI godot_string_to_int(const godot_string *p_self) {
+double GDAPI godot_string_to_float(const godot_string *p_self) {
const String *self = (const String *)p_self;
- return self->to_int();
+ return self->to_float();
}
godot_string GDAPI godot_string_capitalize(const godot_string *p_self) {
@@ -581,11 +635,15 @@ double GDAPI godot_string_char_to_float(const char *p_what) {
return String::to_float(p_what);
}
+double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end) {
+ return String::to_float(p_str, r_end);
+}
+
godot_int GDAPI godot_string_char_to_int(const char *p_what) {
return String::to_int(p_what);
}
-int64_t GDAPI godot_string_wchar_to_int(const wchar_t *p_str) {
+godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str) {
return String::to_int(p_str);
}
@@ -593,42 +651,32 @@ godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int
return String::to_int(p_what, p_len);
}
-int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_len) {
+godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len) {
return String::to_int(p_str, p_len);
}
-int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self) {
+godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self) {
const String *self = (const String *)p_self;
return self->hex_to_int(false);
}
-int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self) {
+godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self) {
const String *self = (const String *)p_self;
return self->hex_to_int();
}
-int64_t GDAPI godot_string_to_int64(const godot_string *p_self) {
+godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice) {
const String *self = (const String *)p_self;
-
- return self->to_int();
-}
-
-double GDAPI godot_string_unicode_char_to_float(const wchar_t *p_str, const wchar_t **r_end) {
- return String::to_float(p_str, r_end);
-}
-
-godot_string GDAPI godot_string_get_slice(const godot_string *p_self, godot_string p_splitter, godot_int p_slice) {
- const String *self = (const String *)p_self;
- String *splitter = (String *)&p_splitter;
+ const String *splitter = (const String *)p_splitter;
godot_string result;
memnew_placement(&result, String(self->get_slice(*splitter, p_slice)));
return result;
}
-godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p_splitter, godot_int p_slice) {
+godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice) {
const String *self = (const String *)p_self;
godot_string result;
memnew_placement(&result, String(self->get_slicec(p_splitter, p_slice)));
@@ -636,221 +684,149 @@ godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p
return result;
}
-godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<String> return_value = self->split(*splitter, false);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
-
- return result;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->split(*splitter, false)));
+ return ret;
}
-godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<String> return_value = self->split(*splitter);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->split(*splitter, true)));
+ return ret;
+}
- return result;
+godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) {
+ const String *self = (const String *)p_self;
+ const String *splitter = (const String *)p_splitter;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->split(*splitter, p_allow_empty, p_maxsplit)));
+ return ret;
}
-godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<float> return_value = self->split_floats(*splitter, false);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
- return result;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, false)));
+ return ret;
}
-godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<float> return_value = self->split_floats(*splitter);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
- return result;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, true)));
+ return ret;
}
-godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_array *p_splitters) {
+godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) {
const String *self = (const String *)p_self;
+ const String *splitter = (const String *)p_splitter;
- Vector<String> splitters;
- Array *splitter_proxy = (Array *)p_splitters;
- splitters.resize(splitter_proxy->size());
- for (int i = 0; i < splitter_proxy->size(); i++) {
- splitters.write[i] = (*splitter_proxy)[i];
- }
-
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<float> return_value = self->split_floats_mk(splitters, false);
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, p_allow_empty, p_maxsplit)));
+ return ret;
+}
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
+godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) {
+ const String *self = (const String *)p_self;
+ const String *splitter = (const String *)p_splitter;
- return result;
+ godot_packed_float32_array ret;
+ memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, false)));
+ return ret;
}
-godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) {
+godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
+ const String *splitter = (const String *)p_splitter;
- Vector<String> splitters;
- Array *splitter_proxy = (Array *)p_splitters;
- splitters.resize(splitter_proxy->size());
- for (int i = 0; i < splitter_proxy->size(); i++) {
- splitters.write[i] = (*splitter_proxy)[i];
- }
-
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<float> return_value = self->split_floats_mk(splitters);
+ godot_packed_float32_array ret;
+ memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, true)));
+ return ret;
+}
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
+godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
+ const String *self = (const String *)p_self;
+ const Vector<String> *splitters = (const Vector<String> *)p_splitters;
- return result;
+ godot_packed_float32_array ret;
+ memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, false)));
+ return ret;
}
-godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<int> return_value = self->split_ints(*splitter, false);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
+ const Vector<String> *splitters = (const Vector<String> *)p_splitters;
- return result;
+ godot_packed_float32_array ret;
+ memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, true)));
+ return ret;
}
-godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_self, const godot_string *p_splitter) {
+godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
const String *splitter = (const String *)p_splitter;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<int> return_value = self->split_ints(*splitter);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
- return result;
+ godot_packed_int32_array ret;
+ memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, false)));
+ return ret;
}
-godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_array *p_splitters) {
+godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
+ const String *splitter = (const String *)p_splitter;
- Vector<String> splitters;
- Array *splitter_proxy = (Array *)p_splitters;
- splitters.resize(splitter_proxy->size());
- for (int i = 0; i < splitter_proxy->size(); i++) {
- splitters.write[i] = (*splitter_proxy)[i];
- }
-
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<int> return_value = self->split_ints_mk(splitters, false);
-
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
-
- return result;
+ godot_packed_int32_array ret;
+ memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, true)));
+ return ret;
}
-godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) {
+godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
const String *self = (const String *)p_self;
+ const Vector<String> *splitters = (const Vector<String> *)p_splitters;
- Vector<String> splitters;
- Array *splitter_proxy = (Array *)p_splitters;
- splitters.resize(splitter_proxy->size());
- for (int i = 0; i < splitter_proxy->size(); i++) {
- splitters.write[i] = (*splitter_proxy)[i];
- }
-
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<int> return_value = self->split_ints_mk(splitters);
+ godot_packed_int32_array ret;
+ memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, false)));
+ return ret;
+}
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
+godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
+ const String *self = (const String *)p_self;
+ const Vector<String> *splitters = (const Vector<String> *)p_splitters;
- return result;
+ godot_packed_int32_array ret;
+ memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, true)));
+ return ret;
}
-godot_array GDAPI godot_string_split_spaces(const godot_string *p_self) {
+godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self) {
const String *self = (const String *)p_self;
- godot_array result;
- memnew_placement(&result, Array);
- Array *proxy = (Array *)&result;
- Vector<String> return_value = self->split_spaces();
- proxy->resize(return_value.size());
- for (int i = 0; i < return_value.size(); i++) {
- (*proxy)[i] = return_value[i];
- }
-
- return result;
+ godot_packed_string_array ret;
+ memnew_placement(&ret, Vector<String>(self->split_spaces()));
+ return ret;
}
-godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, godot_string p_splitter) {
+godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter) {
const String *self = (const String *)p_self;
- String *splitter = (String *)&p_splitter;
+ const String *splitter = (const String *)p_splitter;
return self->get_slice_count(*splitter);
}
-wchar_t GDAPI godot_string_char_lowercase(wchar_t p_char) {
+godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char) {
return String::char_lowercase(p_char);
}
-wchar_t GDAPI godot_string_char_uppercase(wchar_t p_char) {
+godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char) {
return String::char_uppercase(p_char);
}
@@ -894,7 +870,7 @@ godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos
return result;
}
-wchar_t GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) {
+godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) {
const String *self = (const String *)p_self;
return self->ord_at(p_idx);
@@ -917,6 +893,14 @@ godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_po
return result;
}
+godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count) {
+ const String *self = (const String *)p_self;
+ godot_string result;
+ memnew_placement(&result, String(self->repeat(p_count)));
+
+ return result;
+}
+
godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right) {
const String *self = (const String *)p_self;
godot_string result;
@@ -948,7 +932,7 @@ godot_char_string GDAPI godot_string_ascii(const godot_string *p_self) {
return result;
}
-godot_char_string GDAPI godot_string_ascii_extended(const godot_string *p_self) {
+godot_char_string GDAPI godot_string_latin1(const godot_string *p_self) {
const String *self = (const String *)p_self;
godot_char_string result;
@@ -994,6 +978,42 @@ godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot
return result;
}
+godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+
+ godot_char16_string result;
+
+ memnew_placement(&result, Char16String(self->utf16()));
+
+ return result;
+}
+
+godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16) {
+ String *self = (String *)p_self;
+
+ return self->parse_utf16(p_utf16);
+}
+
+godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len) {
+ String *self = (String *)p_self;
+
+ return self->parse_utf16(p_utf16, p_len);
+}
+
+godot_string GDAPI godot_string_chars_to_utf16(const char16_t *p_utf16) {
+ godot_string result;
+ memnew_placement(&result, String(String::utf16(p_utf16)));
+
+ return result;
+}
+
+godot_string GDAPI godot_string_chars_to_utf16_with_len(const char16_t *p_utf16, godot_int p_len) {
+ godot_string result;
+ memnew_placement(&result, String(String::utf16(p_utf16, p_len)));
+
+ return result;
+}
+
uint32_t GDAPI godot_string_hash(const godot_string *p_self) {
const String *self = (const String *)p_self;
@@ -1014,28 +1034,18 @@ uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_
return String::hash(p_cstr, p_len);
}
-uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str) {
+uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str) {
return String::hash(p_str);
}
-uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len) {
+uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len) {
return String::hash(p_str, p_len);
}
godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) {
const String *self = (const String *)p_self;
- Vector<uint8_t> tmp_result = self->md5_buffer();
-
godot_packed_byte_array result;
- memnew_placement(&result, PackedByteArray);
- PackedByteArray *proxy = (PackedByteArray *)&result;
- uint8_t *proxy_writer = proxy->ptrw();
- proxy->resize(tmp_result.size());
-
- for (int i = 0; i < tmp_result.size(); i++) {
- proxy_writer[i] = tmp_result[i];
- }
-
+ memnew_placement(&result, PackedByteArray(self->md5_buffer()));
return result;
}
@@ -1047,23 +1057,28 @@ godot_string GDAPI godot_string_md5_text(const godot_string *p_self) {
return result;
}
-godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) {
+godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self) {
const String *self = (const String *)p_self;
- Vector<uint8_t> tmp_result = self->sha256_buffer();
-
godot_packed_byte_array result;
- memnew_placement(&result, PackedByteArray);
- PackedByteArray *proxy = (PackedByteArray *)&result;
- uint8_t *proxy_writer = proxy->ptrw();
- proxy->resize(tmp_result.size());
+ memnew_placement(&result, PackedByteArray(self->sha1_buffer()));
+ return result;
+}
- for (int i = 0; i < tmp_result.size(); i++) {
- proxy_writer[i] = tmp_result[i];
- }
+godot_string GDAPI godot_string_sha1_text(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+ godot_string result;
+ memnew_placement(&result, String(self->sha1_text()));
return result;
}
+godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+ godot_packed_byte_array result;
+ memnew_placement(&result, PackedByteArray(self->sha256_buffer()));
+ return result;
+}
+
godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) {
const String *self = (const String *)p_self;
godot_string result;
@@ -1206,15 +1221,6 @@ godot_string GDAPI godot_string_json_escape(const godot_string *p_self) {
return result;
}
-godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->word_wrap(p_chars_per_line);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) {
const String *self = (const String *)p_self;
godot_string result;
@@ -1260,6 +1266,22 @@ godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) {
return result;
}
+godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts) {
+ const String *self = (const String *)p_self;
+ const Vector<String> *parts = (const Vector<String> *)p_parts;
+ godot_string result;
+ String return_value = self->join(*parts);
+ memnew_placement(&result, String(return_value));
+
+ return result;
+}
+
+godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+
+ return self->is_valid_filename();
+}
+
godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self) {
const String *self = (const String *)p_self;
@@ -1325,31 +1347,22 @@ godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const go
return result;
}
-godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars) {
+godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars) {
const String *self = (const String *)p_self;
String *chars = (String *)p_chars;
godot_string result;
- String return_value = self->rstrip(*chars);
+ String return_value = self->lstrip(*chars);
memnew_placement(&result, String(return_value));
return result;
}
-godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor,
- const godot_bool p_allow_empty, const godot_int p_maxsplit) {
+godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars) {
const String *self = (const String *)p_self;
- String *divisor = (String *)p_divisor;
-
- godot_packed_string_array result;
- memnew_placement(&result, PackedStringArray);
- PackedStringArray *proxy = (PackedStringArray *)&result;
- String *proxy_writer = proxy->ptrw();
- Vector<String> tmp_result = self->rsplit(*divisor, p_allow_empty, p_maxsplit);
- proxy->resize(tmp_result.size());
-
- for (int i = 0; i < tmp_result.size(); i++) {
- proxy_writer[i] = tmp_result[i];
- }
+ String *chars = (String *)p_chars;
+ godot_string result;
+ String return_value = self->rstrip(*chars);
+ memnew_placement(&result, String(return_value));
return result;
}
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 8ccf44ff1a..82bfbd23de 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -3732,6 +3732,27 @@
]
},
{
+ "name": "godot_char16_string_length",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_char16_string *", "p_cs"]
+ ]
+ },
+ {
+ "name": "godot_char16_string_get_data",
+ "return_type": "const char16_t *",
+ "arguments": [
+ ["const godot_char16_string *", "p_cs"]
+ ]
+ },
+ {
+ "name": "godot_char16_string_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_char16_string *", "p_cs"]
+ ]
+ },
+ {
"name": "godot_string_new",
"return_type": "void",
"arguments": [
@@ -3747,7 +3768,83 @@
]
},
{
- "name": "godot_string_new_with_wide_string",
+ "name": "godot_string_new_with_latin1_chars",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char *", "p_contents"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf8_chars",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char *", "p_contents"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf16_chars",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char16_t *", "p_contents"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf32_chars",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char32_t *", "p_contents"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_wide_chars",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const wchar_t *", "p_contents"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_latin1_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf8_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf16_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char16_t *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf32_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ ["godot_string *", "r_dest"],
+ ["const char32_t *", "p_contents"],
+ ["const int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_wide_chars_and_len",
"return_type": "void",
"arguments": [
["godot_string *", "r_dest"],
@@ -3757,7 +3854,7 @@
},
{
"name": "godot_string_operator_index",
- "return_type": "const wchar_t *",
+ "return_type": "const godot_char_type *",
"arguments": [
["godot_string *", "p_self"],
["const godot_int", "p_idx"]
@@ -3765,15 +3862,15 @@
},
{
"name": "godot_string_operator_index_const",
- "return_type": "wchar_t",
+ "return_type": "godot_char_type",
"arguments": [
["const godot_string *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_string_wide_str",
- "return_type": "const wchar_t *",
+ "name": "godot_string_get_data",
+ "return_type": "const godot_char_type *",
"arguments": [
["const godot_string *", "p_self"]
]
@@ -3807,7 +3904,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"],
["godot_int", "p_to"]
]
@@ -3817,7 +3914,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"],
["godot_int", "p_to"]
]
@@ -3878,7 +3975,7 @@
},
{
"name": "godot_string_bigrams",
- "return_type": "godot_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_string *", "p_self"]
]
@@ -3887,7 +3984,7 @@
"name": "godot_string_chr",
"return_type": "godot_string",
"arguments": [
- ["wchar_t", "p_character"]
+ ["godot_char_type", "p_character"]
]
},
{
@@ -3899,11 +3996,19 @@
]
},
{
+ "name": "godot_string_ends_with_char_array",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const char *", "p_char_array"]
+ ]
+ },
+ {
"name": "godot_string_find",
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
+ ["const godot_string *", "p_what"]
]
},
{
@@ -3911,7 +4016,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"]
]
},
@@ -3920,7 +4025,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"]
+ ["const godot_packed_string_array *", "p_keys"]
]
},
{
@@ -3928,7 +4033,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"],
+ ["const godot_packed_string_array *", "p_keys"],
["godot_int", "p_from"]
]
},
@@ -3937,7 +4042,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_keys"],
+ ["const godot_packed_string_array *", "p_keys"],
["godot_int", "p_from"],
["godot_int *", "r_key"]
]
@@ -3947,7 +4052,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
+ ["const godot_string *", "p_what"]
]
},
{
@@ -3955,7 +4060,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"]
]
},
@@ -3985,26 +4090,12 @@
]
},
{
- "name": "godot_string_hex_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hex_to_int_without_prefix",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
"name": "godot_string_insert",
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
["godot_int", "p_at_pos"],
- ["godot_string", "p_string"]
+ ["const godot_string *", "p_string"]
]
},
{
@@ -4137,8 +4228,8 @@
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
+ ["const godot_string *", "p_key"],
+ ["const godot_string *", "p_with"]
]
},
{
@@ -4146,8 +4237,8 @@
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
+ ["const godot_string *", "p_key"],
+ ["const godot_string *", "p_with"]
]
},
{
@@ -4155,8 +4246,8 @@
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_key"],
- ["godot_string", "p_with"]
+ ["const godot_string *", "p_key"],
+ ["const godot_string *", "p_with"]
]
},
{
@@ -4164,7 +4255,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
+ ["const godot_string *", "p_what"]
]
},
{
@@ -4172,7 +4263,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"]
+ ["const godot_string *", "p_what"]
]
},
{
@@ -4180,7 +4271,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"]
]
},
@@ -4189,7 +4280,7 @@
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_what"],
+ ["const godot_string *", "p_what"],
["godot_int", "p_from"]
]
},
@@ -4237,15 +4328,15 @@
]
},
{
- "name": "godot_string_to_float",
- "return_type": "double",
+ "name": "godot_string_to_int",
+ "return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"]
]
},
{
- "name": "godot_string_to_int",
- "return_type": "godot_int",
+ "name": "godot_string_to_float",
+ "return_type": "double",
"arguments": [
["const godot_string *", "p_self"]
]
@@ -4279,6 +4370,14 @@
]
},
{
+ "name": "godot_string_wchar_to_float",
+ "return_type": "double",
+ "arguments": [
+ ["const wchar_t *", "p_str"],
+ ["const wchar_t **", "r_end"]
+ ]
+ },
+ {
"name": "godot_string_char_to_int",
"return_type": "godot_int",
"arguments": [
@@ -4287,7 +4386,7 @@
},
{
"name": "godot_string_wchar_to_int",
- "return_type": "int64_t",
+ "return_type": "godot_int",
"arguments": [
["const wchar_t *", "p_str"]
]
@@ -4301,48 +4400,33 @@
]
},
{
- "name": "godot_string_char_to_int64_with_len",
- "return_type": "int64_t",
+ "name": "godot_string_wchar_to_int_with_len",
+ "return_type": "godot_int",
"arguments": [
["const wchar_t *", "p_str"],
["int", "p_len"]
]
},
{
- "name": "godot_string_hex_to_int64",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hex_to_int64_with_prefix",
- "return_type": "int64_t",
+ "name": "godot_string_hex_to_int",
+ "return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"]
]
},
{
- "name": "godot_string_to_int64",
- "return_type": "int64_t",
+ "name": "godot_string_hex_to_int_with_prefix",
+ "return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"]
]
},
{
- "name": "godot_string_unicode_char_to_float",
- "return_type": "double",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["const wchar_t **", "r_end"]
- ]
- },
- {
"name": "godot_string_get_slice_count",
"return_type": "godot_int",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_splitter"]
+ ["const godot_string *", "p_splitter"]
]
},
{
@@ -4350,7 +4434,7 @@
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["godot_string", "p_splitter"],
+ ["const godot_string *", "p_splitter"],
["godot_int", "p_slice"]
]
},
@@ -4359,13 +4443,13 @@
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["wchar_t", "p_splitter"],
+ ["godot_char_type", "p_splitter"],
["godot_int", "p_slice"]
]
},
{
"name": "godot_string_split",
- "return_type": "godot_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
@@ -4373,23 +4457,59 @@
},
{
"name": "godot_string_split_allow_empty",
- "return_type": "godot_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
]
},
{
+ "name": "godot_string_split_with_maxsplit",
+ "return_type": "godot_packed_string_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"],
+ ["const godot_bool", "p_allow_empty"],
+ ["const godot_int", "p_maxsplit"]
+ ]
+ },
+ {
+ "name": "godot_string_rsplit",
+ "return_type": "godot_packed_string_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_rsplit_allow_empty",
+ "return_type": "godot_packed_string_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"]
+ ]
+ },
+ {
+ "name": "godot_string_rsplit_with_maxsplit",
+ "return_type": "godot_packed_string_array",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_string *", "p_splitter"],
+ ["const godot_bool", "p_allow_empty"],
+ ["const godot_int", "p_maxsplit"]
+ ]
+ },
+ {
"name": "godot_string_split_floats",
- "return_type": "godot_array",
+ "return_type": "godot_packed_float32_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
]
},
{
- "name": "godot_string_split_floats_allows_empty",
- "return_type": "godot_array",
+ "name": "godot_string_split_floats_allow_empty",
+ "return_type": "godot_packed_float32_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
@@ -4397,31 +4517,31 @@
},
{
"name": "godot_string_split_floats_mk",
- "return_type": "godot_array",
+ "return_type": "godot_packed_float32_array",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
+ ["const godot_packed_string_array *", "p_splitters"]
]
},
{
- "name": "godot_string_split_floats_mk_allows_empty",
- "return_type": "godot_array",
+ "name": "godot_string_split_floats_mk_allow_empty",
+ "return_type": "godot_packed_float32_array",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
+ ["const godot_packed_string_array *", "p_splitters"]
]
},
{
"name": "godot_string_split_ints",
- "return_type": "godot_array",
+ "return_type": "godot_packed_int32_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
]
},
{
- "name": "godot_string_split_ints_allows_empty",
- "return_type": "godot_array",
+ "name": "godot_string_split_ints_allow_empty",
+ "return_type": "godot_packed_int32_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_splitter"]
@@ -4429,29 +4549,29 @@
},
{
"name": "godot_string_split_ints_mk",
- "return_type": "godot_array",
+ "return_type": "godot_packed_int32_array",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
+ ["const godot_packed_string_array *", "p_splitters"]
]
},
{
- "name": "godot_string_split_ints_mk_allows_empty",
- "return_type": "godot_array",
+ "name": "godot_string_split_ints_mk_allow_empty",
+ "return_type": "godot_packed_int32_array",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_array *", "p_splitters"]
+ ["const godot_packed_string_array *", "p_splitters"]
]
},
{
"name": "godot_string_split_spaces",
- "return_type": "godot_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_string *", "p_self"]
]
},
{
- "name": "godot_string_rstrip",
+ "name": "godot_string_lstrip",
"return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
@@ -4459,13 +4579,11 @@
]
},
{
- "name": "godot_string_rsplit",
- "return_type": "godot_packed_string_array",
+ "name": "godot_string_rstrip",
+ "return_type": "godot_string",
"arguments": [
["const godot_string *", "p_self"],
- ["const godot_string *", "p_divisor"],
- ["const godot_bool", "p_allow_empty"],
- ["const godot_int", "p_maxsplit"]
+ ["const godot_string *", "p_chars"]
]
},
{
@@ -4486,16 +4604,16 @@
},
{
"name": "godot_string_char_lowercase",
- "return_type": "wchar_t",
+ "return_type": "godot_char_type",
"arguments": [
- ["wchar_t", "p_char"]
+ ["godot_char_type", "p_char"]
]
},
{
"name": "godot_string_char_uppercase",
- "return_type": "wchar_t",
+ "return_type": "godot_char_type",
"arguments": [
- ["wchar_t", "p_char"]
+ ["godot_char_type", "p_char"]
]
},
{
@@ -4536,7 +4654,7 @@
},
{
"name": "godot_string_ord_at",
- "return_type": "wchar_t",
+ "return_type": "godot_char_type",
"arguments": [
["const godot_string *", "p_self"],
["godot_int", "p_idx"]
@@ -4559,6 +4677,14 @@
]
},
{
+ "name": "godot_string_repeat",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_int", "p_count"]
+ ]
+ },
+ {
"name": "godot_string_strip_edges",
"return_type": "godot_string",
"arguments": [
@@ -4591,7 +4717,7 @@
]
},
{
- "name": "godot_string_ascii_extended",
+ "name": "godot_string_latin1",
"return_type": "godot_char_string",
"arguments": [
["const godot_string *", "p_self"]
@@ -4622,17 +4748,26 @@
]
},
{
- "name": "godot_string_chars_to_utf8",
- "return_type": "godot_string",
+ "name": "godot_string_utf16",
+ "return_type": "godot_char16_string",
"arguments": [
- ["const char *", "p_utf8"]
+ ["const godot_string *", "p_self"]
]
},
{
- "name": "godot_string_chars_to_utf8_with_len",
- "return_type": "godot_string",
+ "name": "godot_string_parse_utf16",
+ "return_type": "godot_bool",
"arguments": [
- ["const char *", "p_utf8"],
+ ["godot_string *", "p_self"],
+ ["const char16_t *", "p_utf16"]
+ ]
+ },
+ {
+ "name": "godot_string_parse_utf16_with_len",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["godot_string *", "p_self"],
+ ["const char16_t *", "p_utf16"],
["godot_int", "p_len"]
]
},
@@ -4666,14 +4801,14 @@
]
},
{
- "name": "godot_string_hash_utf8_chars",
+ "name": "godot_string_hash_wide_chars",
"return_type": "uint32_t",
"arguments": [
["const wchar_t *", "p_str"]
]
},
{
- "name": "godot_string_hash_utf8_chars_with_len",
+ "name": "godot_string_hash_wide_chars_with_len",
"return_type": "uint32_t",
"arguments": [
["const wchar_t *", "p_str"],
@@ -4695,6 +4830,20 @@
]
},
{
+ "name": "godot_string_sha1_buffer",
+ "return_type": "godot_packed_byte_array",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_string_sha1_text",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
"name": "godot_string_sha256_buffer",
"return_type": "godot_packed_byte_array",
"arguments": [
@@ -4823,14 +4972,6 @@
]
},
{
- "name": "godot_string_word_wrap",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_chars_per_line"]
- ]
- },
- {
"name": "godot_string_xml_escape",
"return_type": "godot_string",
"arguments": [
@@ -4866,6 +5007,21 @@
]
},
{
+ "name": "godot_string_join",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["const godot_packed_string_array *", "p_parts"]
+ ]
+ },
+ {
+ "name": "godot_string_is_valid_filename",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_string *", "p_self"]
+ ]
+ },
+ {
"name": "godot_string_is_valid_float",
"return_type": "godot_bool",
"arguments": [
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index fdd755845f..f0f095ddf5 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -318,6 +318,7 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
platform_ios.name = "iOS";
platform_ios.entries.push_back("armv7");
platform_ios.entries.push_back("arm64");
+ platform_ios.entries.push_back("x86_64");
// iOS can use both Static and Dynamic libraries.
// Frameworks is actually a folder with files.
platform_ios.library_extension = "*.framework; Framework, *.xcframework; Binary Framework, *.a; Static Library, *.dylib; Dynamic Library";
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index d89383dc1b..0582d95f63 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -38,10 +38,11 @@ extern "C" {
#include <stdint.h>
#include <wchar.h>
-typedef wchar_t godot_char_type;
+typedef char32_t godot_char_type;
#define GODOT_STRING_SIZE sizeof(void *)
#define GODOT_CHAR_STRING_SIZE sizeof(void *)
+#define GODOT_CHAR16_STRING_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
@@ -58,6 +59,13 @@ typedef struct {
} godot_char_string;
#endif
+#ifndef GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_CHAR16_STRING_SIZE];
+} godot_char16_string;
+#endif
+
// reduce extern "C" nesting for VS2013
#ifdef __cplusplus
}
@@ -75,13 +83,28 @@ godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs);
const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs);
void GDAPI godot_char_string_destroy(godot_char_string *p_cs);
+godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs);
+const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs);
+void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs);
+
void GDAPI godot_string_new(godot_string *r_dest);
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
-void GDAPI godot_string_new_with_wide_string(godot_string *r_dest, const wchar_t *p_contents, const int p_size);
-const wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx);
-wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx);
-const wchar_t GDAPI *godot_string_wide_str(const godot_string *p_self);
+void GDAPI godot_string_new_with_latin1_chars(godot_string *r_dest, const char *p_contents);
+void GDAPI godot_string_new_with_utf8_chars(godot_string *r_dest, const char *p_contents);
+void GDAPI godot_string_new_with_utf16_chars(godot_string *r_dest, const char16_t *p_contents);
+void GDAPI godot_string_new_with_utf32_chars(godot_string *r_dest, const char32_t *p_contents);
+void GDAPI godot_string_new_with_wide_chars(godot_string *r_dest, const wchar_t *p_contents);
+
+void GDAPI godot_string_new_with_latin1_chars_and_len(godot_string *r_dest, const char *p_contents, const int p_size);
+void GDAPI godot_string_new_with_utf8_chars_and_len(godot_string *r_dest, const char *p_contents, const int p_size);
+void GDAPI godot_string_new_with_utf16_chars_and_len(godot_string *r_dest, const char16_t *p_contents, const int p_size);
+void GDAPI godot_string_new_with_utf32_chars_and_len(godot_string *r_dest, const char32_t *p_contents, const int p_size);
+void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const wchar_t *p_contents, const int p_size);
+
+const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx);
+godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx);
+const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self);
godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b);
godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b);
@@ -89,7 +112,7 @@ godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const
/* Standard size stuff */
-godot_int GDAPI godot_string_length(const godot_string *p_self);
+/*+++*/ godot_int GDAPI godot_string_length(const godot_string *p_self);
/* Helpers */
@@ -99,24 +122,25 @@ signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, c
godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string);
godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array);
-godot_array GDAPI godot_string_bigrams(const godot_string *p_self);
-godot_string GDAPI godot_string_chr(wchar_t p_character);
+godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self);
+godot_string GDAPI godot_string_chr(godot_char_type p_character);
godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string);
-godot_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);
-godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_array *p_keys, godot_int p_from);
-godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key);
-godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what);
-godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
+godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array);
+godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to);
+godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to);
+godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what);
+godot_int GDAPI godot_string_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
+godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys);
+godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from);
+godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key);
+godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what);
+godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values);
godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder);
godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len);
godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self);
-godot_int GDAPI godot_string_hex_to_int_without_prefix(const godot_string *p_self);
-godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, godot_string p_string);
+godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self);
+godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string);
godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self);
godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string);
godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string);
@@ -133,13 +157,13 @@ godot_string GDAPI godot_string_num_scientific(double p_num);
godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals);
godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits);
godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits);
-godot_string GDAPI godot_string_replace_first(const godot_string *p_self, godot_string p_key, godot_string p_with);
-godot_string GDAPI godot_string_replace(const godot_string *p_self, godot_string p_key, godot_string p_with);
-godot_string GDAPI godot_string_replacen(const godot_string *p_self, godot_string p_key, godot_string p_with);
-godot_int GDAPI godot_string_rfind(const godot_string *p_self, godot_string p_what);
-godot_int GDAPI godot_string_rfindn(const godot_string *p_self, godot_string p_what);
-godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
-godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
+godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
+godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
+godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
+godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what);
+godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what);
+godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
+godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length);
godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character);
godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string);
@@ -151,64 +175,79 @@ godot_int GDAPI godot_string_to_int(const godot_string *p_self);
godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self);
godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self);
godot_string GDAPI godot_string_capitalize(const godot_string *p_self);
+
double GDAPI godot_string_char_to_float(const char *p_what);
+double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end);
+
godot_int GDAPI godot_string_char_to_int(const char *p_what);
-int64_t GDAPI godot_string_wchar_to_int(const wchar_t *p_str);
+godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str);
+
godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len);
-int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_len);
-int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self);
-int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self);
-int64_t GDAPI godot_string_to_int64(const godot_string *p_self);
-double GDAPI godot_string_unicode_char_to_float(const wchar_t *p_str, const wchar_t **r_end);
-
-godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, godot_string p_splitter);
-godot_string GDAPI godot_string_get_slice(const godot_string *p_self, godot_string p_splitter, godot_int p_slice);
-godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p_splitter, godot_int p_slice);
-
-godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_array *p_splitters);
-godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters);
-godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_array *p_splitters);
-godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters);
-godot_array GDAPI godot_string_split_spaces(const godot_string *p_self);
-
-wchar_t GDAPI godot_string_char_lowercase(wchar_t p_char);
-wchar_t GDAPI godot_string_char_uppercase(wchar_t p_char);
+godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len);
+
+godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter);
+godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice);
+godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice);
+
+godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit);
+
+godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit);
+
+godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters);
+godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters);
+godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
+godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters);
+godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters);
+
+godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self);
+
+godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char);
+godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char);
godot_string GDAPI godot_string_to_lower(const godot_string *p_self);
godot_string GDAPI godot_string_to_upper(const godot_string *p_self);
godot_string GDAPI godot_string_get_basename(const godot_string *p_self);
godot_string GDAPI godot_string_get_extension(const godot_string *p_self);
godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos);
-wchar_t GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx);
+godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx);
godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file);
godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos);
+godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count);
godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right);
godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self);
void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars);
godot_char_string GDAPI godot_string_ascii(const godot_string *p_self);
-godot_char_string GDAPI godot_string_ascii_extended(const godot_string *p_self);
+godot_char_string GDAPI godot_string_latin1(const godot_string *p_self);
+
godot_char_string GDAPI godot_string_utf8(const godot_string *p_self);
godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8);
godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len);
-godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8);
-godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot_int p_len);
+
+godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self);
+godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16);
+godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len);
uint32_t GDAPI godot_string_hash(const godot_string *p_self);
uint64_t GDAPI godot_string_hash64(const godot_string *p_self);
+
uint32_t GDAPI godot_string_hash_chars(const char *p_cstr);
uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len);
-uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str);
-uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len);
+uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str);
+uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len);
+
godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self);
godot_string GDAPI godot_string_md5_text(const godot_string *p_self);
+godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self);
+godot_string GDAPI godot_string_sha1_text(const godot_string *p_self);
godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self);
godot_string GDAPI godot_string_sha256_text(const godot_string *p_self);
@@ -231,14 +270,15 @@ godot_string GDAPI godot_string_c_unescape(const godot_string *p_self);
godot_string GDAPI godot_string_http_escape(const godot_string *p_self);
godot_string GDAPI godot_string_http_unescape(const godot_string *p_self);
godot_string GDAPI godot_string_json_escape(const godot_string *p_self);
-godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line);
godot_string GDAPI godot_string_xml_escape(const godot_string *p_self);
godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self);
godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self);
godot_string GDAPI godot_string_percent_decode(const godot_string *p_self);
godot_string GDAPI godot_string_percent_encode(const godot_string *p_self);
+godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts);
+godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self);
godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self);
godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix);
godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self);
@@ -249,8 +289,8 @@ godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self);
godot_string GDAPI godot_string_dedent(const godot_string *p_self);
godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix);
godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix);
+godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars);
godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars);
-godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor, const godot_bool p_allow_empty, const godot_int p_maxsplit);
void GDAPI godot_string_destroy(godot_string *p_self);
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 019fa0d1f8..8dbaec4e75 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -176,10 +176,10 @@ List<ClassAPI> generate_c_api_classes() {
// Register global constants as a fake GlobalConstants singleton class
{
ClassAPI global_constants_api;
- global_constants_api.class_name = L"GlobalConstants";
+ global_constants_api.class_name = "GlobalConstants";
global_constants_api.api_type = ClassDB::API_CORE;
global_constants_api.is_singleton = true;
- global_constants_api.singleton_name = L"GlobalConstants";
+ global_constants_api.singleton_name = "GlobalConstants";
global_constants_api.is_instanciable = false;
const int constants_count = GlobalConstants::get_global_constant_count();
for (int i = 0; i < constants_count; ++i) {
diff --git a/modules/gdnative/tests/test_string.h b/modules/gdnative/tests/test_string.h
new file mode 100644
index 0000000000..aeb855a1c4
--- /dev/null
+++ b/modules/gdnative/tests/test_string.h
@@ -0,0 +1,1980 @@
+/*************************************************************************/
+/* test_string.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_GDNATIVE_STRING_H
+#define TEST_GDNATIVE_STRING_H
+
+namespace TestGDNativeString {
+
+#include "gdnative/string.h"
+
+#include "tests/test_macros.h"
+
+int u32scmp(const char32_t *l, const char32_t *r) {
+ for (; *l == *r && *l && *r; l++, r++)
+ ;
+ return *l - *r;
+}
+
+TEST_CASE("[GDNative String] Construct from Latin-1 char string") {
+ godot_string s;
+
+ godot_string_new_with_latin1_chars(&s, "Hello");
+ CHECK(u32scmp(godot_string_get_data(&s), U"Hello") == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_latin1_chars_and_len(&s, "Hello", 3);
+ CHECK(u32scmp(godot_string_get_data(&s), U"Hel") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Construct from wchar_t string") {
+ godot_string s;
+
+ godot_string_new_with_wide_chars(&s, L"Give me");
+ CHECK(u32scmp(godot_string_get_data(&s), U"Give me") == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_wide_chars_and_len(&s, L"Give me", 3);
+ CHECK(u32scmp(godot_string_get_data(&s), U"Giv") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Construct from UTF-8 char string") {
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 };
+ static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+
+ godot_string s;
+
+ godot_string_new_with_utf8_chars(&s, (const char *)u8str);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 5);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf32_chars(&s, u32str);
+ godot_char_string cs = godot_string_utf8(&s);
+ godot_string_parse_utf8(&s, godot_char_string_get_data(&cs));
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+ godot_char_string_destroy(&cs);
+
+ godot_string_new_with_utf32_chars(&s, u32str);
+ cs = godot_string_utf8(&s);
+ godot_string_parse_utf8_with_len(&s, godot_char_string_get_data(&cs), godot_char_string_length(&cs));
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+ godot_char_string_destroy(&cs);
+}
+
+TEST_CASE("[GDNative String] Construct from UTF-8 string with BOM") {
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 };
+ static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+
+ godot_string s;
+
+ godot_string_new_with_utf8_chars(&s, (const char *)u8str);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 8);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Construct from UTF-16 string") {
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 };
+ static const char16_t u16str[] = { 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
+
+ godot_string s;
+
+ godot_string_new_with_utf16_chars(&s, u16str);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf16_chars_and_len(&s, u16str, 4);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf32_chars(&s, u32str);
+ godot_char16_string cs = godot_string_utf16(&s);
+ godot_string_parse_utf16(&s, godot_char16_string_get_data(&cs));
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+ godot_char16_string_destroy(&cs);
+
+ godot_string_new_with_utf32_chars(&s, u32str);
+ cs = godot_string_utf16(&s);
+ godot_string_parse_utf16_with_len(&s, godot_char16_string_get_data(&cs), godot_char16_string_length(&cs));
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+ godot_char16_string_destroy(&cs);
+}
+
+TEST_CASE("[GDNative String] Construct from UTF-16 string with BOM ") {
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 };
+ static const char16_t u16str[] = { 0xFEFF, 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
+ static const char16_t u16str_swap[] = { 0xFFFE, 0x4500, 0x2000, 0x3CD8, 0xA4DF, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
+
+ godot_string s;
+
+ godot_string_new_with_utf16_chars(&s, u16str);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf16_chars(&s, u16str_swap);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf16_chars_and_len(&s, u16str, 5);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_utf16_chars_and_len(&s, u16str_swap, 5);
+ CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Construct string copy") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "Hello");
+ godot_string_new_copy(&t, &s);
+ CHECK(u32scmp(godot_string_get_data(&t), U"Hello") == 0);
+ godot_string_destroy(&t);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Construct empty string") {
+ godot_string s;
+
+ godot_string_new(&s);
+ CHECK(u32scmp(godot_string_get_data(&s), U"") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] ASCII/Latin-1") {
+ godot_string s;
+ godot_string_new_with_utf32_chars(&s, U"Primero Leche");
+
+ godot_char_string cs = godot_string_ascii(&s);
+ CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0);
+ godot_char_string_destroy(&cs);
+
+ cs = godot_string_latin1(&s);
+ CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0);
+ godot_char_string_destroy(&cs);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Comparisons (equal)") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "Test Compare");
+ godot_string_new_with_latin1_chars(&t, "Test Compare");
+ CHECK(godot_string_operator_equal(&s, &t));
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] Comparisons (operator <)") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "Bees");
+
+ godot_string_new_with_latin1_chars(&t, "Elephant");
+ CHECK(godot_string_operator_less(&s, &t));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Amber");
+ CHECK(!godot_string_operator_less(&s, &t));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Beatrix");
+ CHECK(!godot_string_operator_less(&s, &t));
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Concatenation (operator +)") {
+ godot_string s, t, x;
+
+ godot_string_new_with_latin1_chars(&s, "Hel");
+ godot_string_new_with_latin1_chars(&t, "lo");
+ x = godot_string_operator_plus(&s, &t);
+ CHECK(u32scmp(godot_string_get_data(&x), U"Hello") == 0);
+ godot_string_destroy(&x);
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] Testing size and length of string") {
+ godot_string s;
+
+ godot_string_new_with_latin1_chars(&s, "Mellon");
+ CHECK(godot_string_length(&s) == 6);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_latin1_chars(&s, "Mellon1");
+ CHECK(godot_string_length(&s) == 7);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Testing for empty string") {
+ godot_string s;
+
+ godot_string_new_with_latin1_chars(&s, "Mellon");
+ CHECK(!godot_string_empty(&s));
+ godot_string_destroy(&s);
+
+ godot_string_new_with_latin1_chars(&s, "");
+ CHECK(godot_string_empty(&s));
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Test chr") {
+ godot_string s;
+
+ s = godot_string_chr('H');
+ CHECK(u32scmp(godot_string_get_data(&s), U"H") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_chr(0x3012);
+ CHECK(godot_string_operator_index_const(&s, 0) == 0x3012);
+ godot_string_destroy(&s);
+
+ ERR_PRINT_OFF
+ s = godot_string_chr(0xd812);
+ CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Unpaired UTF-16 surrogate
+ godot_string_destroy(&s);
+
+ s = godot_string_chr(0x20d812);
+ CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Outside UTF-32 range
+ godot_string_destroy(&s);
+ ERR_PRINT_ON
+}
+
+TEST_CASE("[GDNative String] Operator []") {
+ godot_string s;
+
+ godot_string_new_with_latin1_chars(&s, "Hello");
+ CHECK(*godot_string_operator_index(&s, 1) == 'e');
+ CHECK(godot_string_operator_index_const(&s, 0) == 'H');
+ CHECK(godot_string_ord_at(&s, 0) == 'H');
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Case function test") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "MoMoNgA");
+
+ t = godot_string_to_upper(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), U"MOMONGA") == 0);
+ godot_string_destroy(&t);
+
+ t = godot_string_to_lower(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), U"momonga") == 0);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Case compare function test") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "MoMoNgA");
+ godot_string_new_with_latin1_chars(&t, "momonga");
+
+ CHECK(godot_string_casecmp_to(&s, &t) != 0);
+ CHECK(godot_string_nocasecmp_to(&s, &t) == 0);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] Natural compare function test") {
+ godot_string s, t;
+
+ godot_string_new_with_latin1_chars(&s, "img2.png");
+ godot_string_new_with_latin1_chars(&t, "img10.png");
+
+ CHECK(godot_string_nocasecmp_to(&s, &t) > 0);
+ CHECK(godot_string_naturalnocasecmp_to(&s, &t) < 0);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] hex_encode_buffer") {
+ static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3 };
+ godot_string s = godot_string_hex_encode_buffer(u8str, 6);
+ CHECK(u32scmp(godot_string_get_data(&s), U"45e3818a8fe3") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Substr") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "Killer Baby");
+ t = godot_string_substr(&s, 3, 4);
+ CHECK(u32scmp(godot_string_get_data(&t), U"ler ") == 0);
+ godot_string_destroy(&t);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Find") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "Pretty Woman Woman");
+
+ godot_string_new_with_latin1_chars(&t, "Revenge of the Monster Truck");
+ CHECK(godot_string_find(&s, &t) == -1);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "tty");
+ CHECK(godot_string_find(&s, &t) == 3);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Wo");
+ CHECK(godot_string_find_from(&s, &t, 9) == 13);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "man");
+ CHECK(godot_string_rfind(&s, &t) == 15);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Find no case") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "Pretty Whale Whale");
+
+ godot_string_new_with_latin1_chars(&t, "WHA");
+ CHECK(godot_string_findn(&s, &t) == 7);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "WHA");
+ CHECK(godot_string_findn_from(&s, &t, 9) == 13);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "WHA");
+ CHECK(godot_string_rfindn(&s, &t) == 13);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Revenge of the Monster SawFish");
+ CHECK(godot_string_findn(&s, &t) == -1);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Find MK") {
+ godot_packed_string_array keys;
+ godot_packed_string_array_new(&keys);
+
+#define PUSH_KEY(x) \
+ { \
+ godot_string t; \
+ godot_string_new_with_latin1_chars(&t, x); \
+ godot_packed_string_array_push_back(&keys, &t); \
+ godot_string_destroy(&t); \
+ }
+
+ PUSH_KEY("sty")
+ PUSH_KEY("tty")
+ PUSH_KEY("man")
+
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, "Pretty Woman");
+ godot_int key = 0;
+
+ CHECK(godot_string_findmk(&s, &keys) == 3);
+ CHECK(godot_string_findmk_from_in_place(&s, &keys, 0, &key) == 3);
+ CHECK(key == 1);
+
+ CHECK(godot_string_findmk_from(&s, &keys, 5) == 9);
+ CHECK(godot_string_findmk_from_in_place(&s, &keys, 5, &key) == 9);
+ CHECK(key == 2);
+
+ godot_string_destroy(&s);
+ godot_packed_string_array_destroy(&keys);
+
+#undef PUSH_KEY
+}
+
+TEST_CASE("[GDNative String] Find and replace") {
+ godot_string s, c, w;
+ godot_string_new_with_latin1_chars(&s, "Happy Birthday, Anna!");
+ godot_string_new_with_latin1_chars(&c, "Birthday");
+ godot_string_new_with_latin1_chars(&w, "Halloween");
+ godot_string t = godot_string_replace(&s, &c, &w);
+ CHECK(u32scmp(godot_string_get_data(&t), U"Happy Halloween, Anna!") == 0);
+ godot_string_destroy(&s);
+ godot_string_destroy(&c);
+ godot_string_destroy(&w);
+
+ godot_string_new_with_latin1_chars(&c, "H");
+ godot_string_new_with_latin1_chars(&w, "W");
+ s = godot_string_replace_first(&t, &c, &w);
+ godot_string_destroy(&t);
+ godot_string_destroy(&c);
+ godot_string_destroy(&w);
+
+ CHECK(u32scmp(godot_string_get_data(&s), U"Wappy Halloween, Anna!") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Insertion") {
+ godot_string s, t, r, u;
+ godot_string_new_with_latin1_chars(&s, "Who is Frederic?");
+ godot_string_new_with_latin1_chars(&t, "?");
+ godot_string_new_with_latin1_chars(&r, " Chopin");
+
+ u = godot_string_insert(&s, godot_string_find(&s, &t), &r);
+ CHECK(u32scmp(godot_string_get_data(&u), U"Who is Frederic Chopin?") == 0);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+ godot_string_destroy(&r);
+ godot_string_destroy(&u);
+}
+
+TEST_CASE("[GDNative String] Number to string") {
+ godot_string s;
+ s = godot_string_num(3.141593);
+ CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_with_decimals(3.141593, 3);
+ CHECK(u32scmp(godot_string_get_data(&s), U"3.142") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_real(3.141593);
+ CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_scientific(30000000);
+ CHECK(u32scmp(godot_string_get_data(&s), U"3e+07") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_int64(3141593, 10);
+ CHECK(u32scmp(godot_string_get_data(&s), U"3141593") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_int64(0xA141593, 16);
+ CHECK(u32scmp(godot_string_get_data(&s), U"a141593") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_num_int64_capitalized(0xA141593, 16, true);
+ CHECK(u32scmp(godot_string_get_data(&s), U"A141593") == 0);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] String to integer") {
+ static const wchar_t *wnums[4] = { L"1237461283", L"- 22", L"0", L" - 1123412" };
+ static const char *nums[4] = { "1237461283", "- 22", "0", " - 1123412" };
+ static const int num[4] = { 1237461283, -22, 0, -1123412 };
+
+ for (int i = 0; i < 4; i++) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, nums[i]);
+ CHECK(godot_string_to_int(&s) == num[i]);
+ godot_string_destroy(&s);
+
+ CHECK(godot_string_char_to_int(nums[i]) == num[i]);
+ CHECK(godot_string_wchar_to_int(wnums[i]) == num[i]);
+ }
+}
+
+TEST_CASE("[GDNative String] Hex to integer") {
+ static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" };
+ static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD };
+ static const bool wo_prefix[4] = { false, true, true, true };
+ static const bool w_prefix[4] = { true, false, true, false };
+
+ for (int i = 0; i < 4; i++) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, nums[i]);
+ CHECK((godot_string_hex_to_int_with_prefix(&s) == num[i]) == w_prefix[i]);
+ CHECK((godot_string_hex_to_int(&s) == num[i]) == wo_prefix[i]);
+ godot_string_destroy(&s);
+ }
+}
+
+TEST_CASE("[GDNative String] String to float") {
+ static const wchar_t *wnums[4] = { L"-12348298412.2", L"0.05", L"2.0002", L" -0.0001" };
+ static const char *nums[4] = { "-12348298412.2", "0.05", "2.0002", " -0.0001" };
+ static const double num[4] = { -12348298412.2, 0.05, 2.0002, -0.0001 };
+
+ for (int i = 0; i < 4; i++) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, nums[i]);
+ CHECK(!(ABS(godot_string_to_float(&s) - num[i]) > 0.00001));
+ godot_string_destroy(&s);
+
+ CHECK(!(ABS(godot_string_char_to_float(nums[i]) - num[i]) > 0.00001));
+ CHECK(!(ABS(godot_string_wchar_to_float(wnums[i], nullptr) - num[i]) > 0.00001));
+ }
+}
+
+TEST_CASE("[GDNative String] CamelCase to underscore") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "TestTestStringGD");
+
+ t = godot_string_camelcase_to_underscore(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), U"Test_Test_String_GD") == 0);
+ godot_string_destroy(&t);
+
+ t = godot_string_camelcase_to_underscore_lowercased(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), U"test_test_string_gd") == 0);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Slicing") {
+ godot_string s, c;
+ godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus");
+ godot_string_new_with_latin1_chars(&c, ",");
+
+ const char32_t *slices[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" };
+ for (int i = 0; i < godot_string_get_slice_count(&s, &c); i++) {
+ godot_string t;
+ t = godot_string_get_slice(&s, &c, i);
+ CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0);
+ godot_string_destroy(&t);
+
+ t = godot_string_get_slicec(&s, U',', i);
+ CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0);
+ godot_string_destroy(&t);
+ }
+
+ godot_string_destroy(&c);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Splitting") {
+ godot_string s, c;
+ godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus");
+ godot_string_new_with_latin1_chars(&c, ",");
+
+ godot_packed_string_array l;
+
+ const char32_t *slices_l[3] = { U"Mars", U"Jupiter", U"Saturn,Uranus" };
+ const char32_t *slices_r[3] = { U"Mars,Jupiter", U"Saturn", U"Uranus" };
+
+ l = godot_string_split_with_maxsplit(&s, &c, true, 2);
+ CHECK(godot_packed_string_array_size(&l) == 3);
+ for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
+ godot_string t = godot_packed_string_array_get(&l, i);
+ CHECK(u32scmp(godot_string_get_data(&t), slices_l[i]) == 0);
+ godot_string_destroy(&t);
+ }
+ godot_packed_string_array_destroy(&l);
+
+ l = godot_string_rsplit_with_maxsplit(&s, &c, true, 2);
+ CHECK(godot_packed_string_array_size(&l) == 3);
+ for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
+ godot_string t = godot_packed_string_array_get(&l, i);
+ CHECK(u32scmp(godot_string_get_data(&t), slices_r[i]) == 0);
+ godot_string_destroy(&t);
+ }
+ godot_packed_string_array_destroy(&l);
+ godot_string_destroy(&s);
+
+ godot_string_new_with_latin1_chars(&s, "Mars Jupiter Saturn Uranus");
+ const char32_t *slices_s[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" };
+ l = godot_string_split_spaces(&s);
+ for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
+ godot_string t = godot_packed_string_array_get(&l, i);
+ CHECK(u32scmp(godot_string_get_data(&t), slices_s[i]) == 0);
+ godot_string_destroy(&t);
+ }
+ godot_packed_string_array_destroy(&l);
+ godot_string_destroy(&s);
+
+ godot_string c1, c2;
+ godot_string_new_with_latin1_chars(&c1, ";");
+ godot_string_new_with_latin1_chars(&c2, " ");
+
+ godot_string_new_with_latin1_chars(&s, "1.2;2.3 4.5");
+ const double slices_d[3] = { 1.2, 2.3, 4.5 };
+
+ godot_packed_float32_array lf = godot_string_split_floats_allow_empty(&s, &c1);
+ CHECK(godot_packed_float32_array_size(&lf) == 2);
+ for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) {
+ CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001);
+ }
+ godot_packed_float32_array_destroy(&lf);
+
+ godot_packed_string_array keys;
+ godot_packed_string_array_new(&keys);
+ godot_packed_string_array_push_back(&keys, &c1);
+ godot_packed_string_array_push_back(&keys, &c2);
+
+ lf = godot_string_split_floats_mk_allow_empty(&s, &keys);
+ CHECK(godot_packed_float32_array_size(&lf) == 3);
+ for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) {
+ CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001);
+ }
+ godot_packed_float32_array_destroy(&lf);
+
+ godot_string_destroy(&s);
+ godot_string_new_with_latin1_chars(&s, "1;2 4");
+ const int slices_i[3] = { 1, 2, 4 };
+
+ godot_packed_int32_array li = godot_string_split_ints_allow_empty(&s, &c1);
+ CHECK(godot_packed_int32_array_size(&li) == 2);
+ for (int i = 0; i < godot_packed_int32_array_size(&li); i++) {
+ CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]);
+ }
+ godot_packed_int32_array_destroy(&li);
+
+ li = godot_string_split_ints_mk_allow_empty(&s, &keys);
+ CHECK(godot_packed_int32_array_size(&li) == 3);
+ for (int i = 0; i < godot_packed_int32_array_size(&li); i++) {
+ CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]);
+ }
+ godot_packed_int32_array_destroy(&li);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&c);
+ godot_string_destroy(&c1);
+ godot_string_destroy(&c2);
+ godot_packed_string_array_destroy(&keys);
+}
+
+TEST_CASE("[GDNative String] Erasing") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "Josephine is such a cute girl!");
+ godot_string_new_with_latin1_chars(&t, "cute ");
+
+ godot_string_erase(&s, godot_string_find(&s, &t), godot_string_length(&t));
+
+ CHECK(u32scmp(godot_string_get_data(&s), U"Josephine is such a girl!") == 0);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+struct test_27_data {
+ char const *data;
+ char const *part;
+ bool expected;
+};
+
+TEST_CASE("[GDNative String] Begins with") {
+ test_27_data tc[] = {
+ { "res://foobar", "res://", true },
+ { "res", "res://", false },
+ { "abc", "abc", true }
+ };
+ size_t count = sizeof(tc) / sizeof(tc[0]);
+ bool state = true;
+ for (size_t i = 0; state && i < count; ++i) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, tc[i].data);
+
+ state = godot_string_begins_with_char_array(&s, tc[i].part) == tc[i].expected;
+ if (state) {
+ godot_string t;
+ godot_string_new_with_latin1_chars(&t, tc[i].part);
+ state = godot_string_begins_with(&s, &t) == tc[i].expected;
+ godot_string_destroy(&t);
+ }
+ godot_string_destroy(&s);
+
+ CHECK(state);
+ if (!state) {
+ break;
+ }
+ };
+ CHECK(state);
+}
+
+TEST_CASE("[GDNative String] Ends with") {
+ test_27_data tc[] = {
+ { "res://foobar", "foobar", true },
+ { "res", "res://", false },
+ { "abc", "abc", true }
+ };
+ size_t count = sizeof(tc) / sizeof(tc[0]);
+ bool state = true;
+ for (size_t i = 0; state && i < count; ++i) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, tc[i].data);
+
+ state = godot_string_ends_with_char_array(&s, tc[i].part) == tc[i].expected;
+ if (state) {
+ godot_string t;
+ godot_string_new_with_latin1_chars(&t, tc[i].part);
+ state = godot_string_ends_with(&s, &t) == tc[i].expected;
+ godot_string_destroy(&t);
+ }
+ godot_string_destroy(&s);
+
+ CHECK(state);
+ if (!state) {
+ break;
+ }
+ };
+ CHECK(state);
+}
+
+TEST_CASE("[GDNative String] format") {
+ godot_string value_format, t;
+ godot_string_new_with_latin1_chars(&value_format, "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\"");
+
+ godot_variant key_v, val_v;
+ godot_dictionary value_dictionary;
+ godot_dictionary_new(&value_dictionary);
+
+ godot_string_new_with_latin1_chars(&t, "red");
+ godot_variant_new_string(&key_v, &t);
+ godot_string_destroy(&t);
+ godot_variant_new_int(&val_v, 10);
+ godot_dictionary_set(&value_dictionary, &key_v, &val_v);
+ godot_variant_destroy(&key_v);
+ godot_variant_destroy(&val_v);
+
+ godot_string_new_with_latin1_chars(&t, "green");
+ godot_variant_new_string(&key_v, &t);
+ godot_string_destroy(&t);
+ godot_variant_new_int(&val_v, 20);
+ godot_dictionary_set(&value_dictionary, &key_v, &val_v);
+ godot_variant_destroy(&key_v);
+ godot_variant_destroy(&val_v);
+
+ godot_string_new_with_latin1_chars(&t, "blue");
+ godot_variant_new_string(&key_v, &t);
+ godot_string_destroy(&t);
+ godot_string_new_with_latin1_chars(&t, "bla");
+ godot_variant_new_string(&val_v, &t);
+ godot_string_destroy(&t);
+ godot_dictionary_set(&value_dictionary, &key_v, &val_v);
+ godot_variant_destroy(&key_v);
+ godot_variant_destroy(&val_v);
+
+ godot_string_new_with_latin1_chars(&t, "alpha");
+ godot_variant_new_string(&key_v, &t);
+ godot_string_destroy(&t);
+ godot_variant_new_real(&val_v, 0.4);
+ godot_dictionary_set(&value_dictionary, &key_v, &val_v);
+ godot_variant_destroy(&key_v);
+ godot_variant_destroy(&val_v);
+
+ godot_variant dict_v;
+ godot_variant_new_dictionary(&dict_v, &value_dictionary);
+ godot_string s = godot_string_format_with_custom_placeholder(&value_format, &dict_v, "$_");
+
+ CHECK(u32scmp(godot_string_get_data(&s), U"red=\"10\" green=\"20\" blue=\"bla\" alpha=\"0.4\"") == 0);
+
+ godot_dictionary_destroy(&value_dictionary);
+ godot_string_destroy(&s);
+ godot_variant_destroy(&dict_v);
+ godot_string_destroy(&value_format);
+}
+
+TEST_CASE("[GDNative String] sprintf") {
+ //godot_string GDAPI (const godot_string *p_self, const godot_array *p_values, godot_bool *p_error);
+ godot_string format, output;
+ godot_array args;
+ bool error;
+
+#define ARRAY_PUSH_STRING(x) \
+ { \
+ godot_variant v; \
+ godot_string t; \
+ godot_string_new_with_latin1_chars(&t, x); \
+ godot_variant_new_string(&v, &t); \
+ godot_string_destroy(&t); \
+ godot_array_push_back(&args, &v); \
+ godot_variant_destroy(&v); \
+ }
+
+#define ARRAY_PUSH_INT(x) \
+ { \
+ godot_variant v; \
+ godot_variant_new_int(&v, x); \
+ godot_array_push_back(&args, &v); \
+ godot_variant_destroy(&v); \
+ }
+
+#define ARRAY_PUSH_REAL(x) \
+ { \
+ godot_variant v; \
+ godot_variant_new_real(&v, x); \
+ godot_array_push_back(&args, &v); \
+ godot_variant_destroy(&v); \
+ }
+
+ godot_array_new(&args);
+
+ // %%
+ godot_string_new_with_latin1_chars(&format, "fish %% frog");
+ godot_array_clear(&args);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish % frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+ //////// INTS
+
+ // Int
+ godot_string_new_with_latin1_chars(&format, "fish %d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Int left padded with zeroes.
+ godot_string_new_with_latin1_chars(&format, "fish %05d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 00005 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Int left padded with spaces.
+ godot_string_new_with_latin1_chars(&format, "fish %5d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Int right padded with spaces.
+ godot_string_new_with_latin1_chars(&format, "fish %-5d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Int with sign (positive).
+ godot_string_new_with_latin1_chars(&format, "fish %+d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish +5 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Negative int.
+ godot_string_new_with_latin1_chars(&format, "fish %d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(-5);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish -5 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Hex (lower)
+ godot_string_new_with_latin1_chars(&format, "fish %x frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(45);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 2d frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Hex (upper)
+ godot_string_new_with_latin1_chars(&format, "fish %X frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(45);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 2D frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Octal
+ godot_string_new_with_latin1_chars(&format, "fish %o frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 143 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+ ////// REALS
+
+ // Real
+ godot_string_new_with_latin1_chars(&format, "fish %f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real left-padded
+ godot_string_new_with_latin1_chars(&format, "fish %11f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real right-padded
+ godot_string_new_with_latin1_chars(&format, "fish %-11f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real given int.
+ godot_string_new_with_latin1_chars(&format, "fish %f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.000000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real with sign (positive).
+ godot_string_new_with_latin1_chars(&format, "fish %+f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish +99.990000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real with 1 decimals.
+ godot_string_new_with_latin1_chars(&format, "fish %.1f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 100.0 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real with 12 decimals.
+ godot_string_new_with_latin1_chars(&format, "fish %.12f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000000000 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Real with no decimals.
+ godot_string_new_with_latin1_chars(&format, "fish %.f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 100 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ /////// Strings.
+
+ // String
+ godot_string_new_with_latin1_chars(&format, "fish %s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // String left-padded
+ godot_string_new_with_latin1_chars(&format, "fish %10s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // String right-padded
+ godot_string_new_with_latin1_chars(&format, "fish %-10s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ ///// Characters
+
+ // Character as string.
+ godot_string_new_with_latin1_chars(&format, "fish %c frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("A");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Character as int.
+ godot_string_new_with_latin1_chars(&format, "fish %c frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(65);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ ///// Dynamic width
+
+ // String dynamic width
+ godot_string_new_with_latin1_chars(&format, "fish %*s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(10);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ REQUIRE(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Int dynamic width
+ godot_string_new_with_latin1_chars(&format, "fish %*d frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(10);
+ ARRAY_PUSH_INT(99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ REQUIRE(u32scmp(godot_string_get_data(&output), U"fish 99 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Float dynamic width
+ godot_string_new_with_latin1_chars(&format, "fish %*.*f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_INT(10);
+ ARRAY_PUSH_INT(3);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error == false);
+ CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990 frog") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ ///// Errors
+
+ // More formats than arguments.
+ godot_string_new_with_latin1_chars(&format, "fish %s %s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"not enough arguments for format string") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // More arguments than formats.
+ godot_string_new_with_latin1_chars(&format, "fish %s frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("hello");
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"not all arguments converted during string formatting") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Incomplete format.
+ godot_string_new_with_latin1_chars(&format, "fish %10");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"incomplete format") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Bad character in format string
+ godot_string_new_with_latin1_chars(&format, "fish %&f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"unsupported format character") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Too many decimals.
+ godot_string_new_with_latin1_chars(&format, "fish %2.2.2f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"too many decimal points in format") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // * not a number
+ godot_string_new_with_latin1_chars(&format, "fish %*f frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("cheese");
+ ARRAY_PUSH_REAL(99.99);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"* wants number") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Character too long.
+ godot_string_new_with_latin1_chars(&format, "fish %c frog");
+ godot_array_clear(&args);
+ ARRAY_PUSH_STRING("sc");
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ // Character bad type.
+ godot_string_new_with_latin1_chars(&format, "fish %c frog");
+ godot_array_clear(&args);
+ godot_array t;
+ godot_array_new(&t);
+ godot_variant v;
+ godot_variant_new_array(&v, &t);
+ godot_array_destroy(&t);
+ godot_array_push_back(&args, &v);
+ godot_variant_destroy(&v);
+ output = godot_string_sprintf(&format, &args, &error);
+ REQUIRE(error);
+ CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0);
+ godot_string_destroy(&format);
+ godot_string_destroy(&output);
+
+ godot_array_destroy(&args);
+#undef ARRAY_PUSH_INT
+#undef ARRAY_PUSH_REAL
+#undef ARRAY_PUSH_STRING
+}
+
+TEST_CASE("[GDNative String] is_numeric") {
+#define IS_NUM_TEST(x, r) \
+ { \
+ godot_string t; \
+ godot_string_new_with_latin1_chars(&t, x); \
+ CHECK(godot_string_is_numeric(&t) == r); \
+ godot_string_destroy(&t); \
+ }
+
+ IS_NUM_TEST("12", true);
+ IS_NUM_TEST("1.2", true);
+ IS_NUM_TEST("AF", false);
+ IS_NUM_TEST("-12", true);
+ IS_NUM_TEST("-1.2", true);
+
+#undef IS_NUM_TEST
+}
+
+TEST_CASE("[GDNative String] pad") {
+ godot_string s, c;
+ godot_string_new_with_latin1_chars(&s, "test");
+ godot_string_new_with_latin1_chars(&c, "x");
+
+ godot_string l = godot_string_lpad_with_custom_character(&s, 10, &c);
+ CHECK(u32scmp(godot_string_get_data(&l), U"xxxxxxtest") == 0);
+ godot_string_destroy(&l);
+
+ godot_string r = godot_string_rpad_with_custom_character(&s, 10, &c);
+ CHECK(u32scmp(godot_string_get_data(&r), U"testxxxxxx") == 0);
+ godot_string_destroy(&r);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&c);
+
+ godot_string_new_with_latin1_chars(&s, "10.10");
+ c = godot_string_pad_decimals(&s, 4);
+ CHECK(u32scmp(godot_string_get_data(&c), U"10.1000") == 0);
+ godot_string_destroy(&c);
+ c = godot_string_pad_zeros(&s, 4);
+ CHECK(u32scmp(godot_string_get_data(&c), U"0010.10") == 0);
+ godot_string_destroy(&c);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] is_subsequence_of") {
+ godot_string a, t;
+ godot_string_new_with_latin1_chars(&a, "is subsequence of");
+
+ godot_string_new_with_latin1_chars(&t, "sub");
+ CHECK(godot_string_is_subsequence_of(&t, &a));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Sub");
+ CHECK(!godot_string_is_subsequence_of(&t, &a));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Sub");
+ CHECK(godot_string_is_subsequence_ofi(&t, &a));
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&a);
+}
+
+TEST_CASE("[GDNative String] match") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "*.png");
+
+ godot_string_new_with_latin1_chars(&t, "img1.png");
+ CHECK(godot_string_match(&t, &s));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "img1.jpeg");
+ CHECK(!godot_string_match(&t, &s));
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "img1.Png");
+ CHECK(!godot_string_match(&t, &s));
+ CHECK(godot_string_matchn(&t, &s));
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] IPVX address to string") {
+ godot_string ip;
+
+ godot_string_new_with_latin1_chars(&ip, "192.168.0.1");
+ CHECK(godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "192.368.0.1");
+ CHECK(!godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+ CHECK(godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "2001:0db8:85j3:0000:0000:8a2e:0370:7334");
+ CHECK(!godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "2001:0db8:85f345:0000:0000:8a2e:0370:7334");
+ CHECK(!godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "2001:0db8::0:8a2e:370:7334");
+ CHECK(godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+
+ godot_string_new_with_latin1_chars(&ip, "::ffff:192.168.0.1");
+ CHECK(godot_string_is_valid_ip_address(&ip));
+ godot_string_destroy(&ip);
+}
+
+TEST_CASE("[GDNative String] Capitalize against many strings") {
+#define CAP_TEST(i, o) \
+ godot_string_new_with_latin1_chars(&input, i); \
+ godot_string_new_with_latin1_chars(&output, o); \
+ test = godot_string_capitalize(&input); \
+ CHECK(u32scmp(godot_string_get_data(&output), godot_string_get_data(&test)) == 0); \
+ godot_string_destroy(&input); \
+ godot_string_destroy(&output); \
+ godot_string_destroy(&test);
+
+ godot_string input, output, test;
+
+ CAP_TEST("bytes2var", "Bytes 2 Var");
+ CAP_TEST("linear2db", "Linear 2 Db");
+ CAP_TEST("vector3", "Vector 3");
+ CAP_TEST("sha256", "Sha 256");
+ CAP_TEST("2db", "2 Db");
+ CAP_TEST("PascalCase", "Pascal Case");
+ CAP_TEST("PascalPascalCase", "Pascal Pascal Case");
+ CAP_TEST("snake_case", "Snake Case");
+ CAP_TEST("snake_snake_case", "Snake Snake Case");
+ CAP_TEST("sha256sum", "Sha 256 Sum");
+ CAP_TEST("cat2dog", "Cat 2 Dog");
+ CAP_TEST("function(name)", "Function(name)");
+ CAP_TEST("snake_case_function(snake_case_arg)", "Snake Case Function(snake Case Arg)");
+ CAP_TEST("snake_case_function( snake_case_arg )", "Snake Case Function( Snake Case Arg )");
+
+#undef CAP_TEST
+}
+
+TEST_CASE("[GDNative String] lstrip and rstrip") {
+#define LSTRIP_TEST(x, y, z) \
+ { \
+ godot_string xx, yy, zz, rr; \
+ godot_string_new_with_latin1_chars(&xx, x); \
+ godot_string_new_with_latin1_chars(&yy, y); \
+ godot_string_new_with_latin1_chars(&zz, z); \
+ rr = godot_string_lstrip(&xx, &yy); \
+ state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
+ godot_string_destroy(&xx); \
+ godot_string_destroy(&yy); \
+ godot_string_destroy(&zz); \
+ godot_string_destroy(&rr); \
+ }
+
+#define RSTRIP_TEST(x, y, z) \
+ { \
+ godot_string xx, yy, zz, rr; \
+ godot_string_new_with_latin1_chars(&xx, x); \
+ godot_string_new_with_latin1_chars(&yy, y); \
+ godot_string_new_with_latin1_chars(&zz, z); \
+ rr = godot_string_rstrip(&xx, &yy); \
+ state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
+ godot_string_destroy(&xx); \
+ godot_string_destroy(&yy); \
+ godot_string_destroy(&zz); \
+ godot_string_destroy(&rr); \
+ }
+
+#define LSTRIP_UTF8_TEST(x, y, z) \
+ { \
+ godot_string xx, yy, zz, rr; \
+ godot_string_new_with_utf8_chars(&xx, x); \
+ godot_string_new_with_utf8_chars(&yy, y); \
+ godot_string_new_with_utf8_chars(&zz, z); \
+ rr = godot_string_lstrip(&xx, &yy); \
+ state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
+ godot_string_destroy(&xx); \
+ godot_string_destroy(&yy); \
+ godot_string_destroy(&zz); \
+ godot_string_destroy(&rr); \
+ }
+
+#define RSTRIP_UTF8_TEST(x, y, z) \
+ { \
+ godot_string xx, yy, zz, rr; \
+ godot_string_new_with_utf8_chars(&xx, x); \
+ godot_string_new_with_utf8_chars(&yy, y); \
+ godot_string_new_with_utf8_chars(&zz, z); \
+ rr = godot_string_rstrip(&xx, &yy); \
+ state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
+ godot_string_destroy(&xx); \
+ godot_string_destroy(&yy); \
+ godot_string_destroy(&zz); \
+ godot_string_destroy(&rr); \
+ }
+
+ bool state = true;
+
+ // strip none
+ LSTRIP_TEST("abc", "", "abc");
+ RSTRIP_TEST("abc", "", "abc");
+ // strip one
+ LSTRIP_TEST("abc", "a", "bc");
+ RSTRIP_TEST("abc", "c", "ab");
+ // strip lots
+ LSTRIP_TEST("bababbababccc", "ab", "ccc");
+ RSTRIP_TEST("aaabcbcbcbbcbbc", "cb", "aaa");
+ // strip empty string
+ LSTRIP_TEST("", "", "");
+ RSTRIP_TEST("", "", "");
+ // strip to empty string
+ LSTRIP_TEST("abcabcabc", "bca", "");
+ RSTRIP_TEST("abcabcabc", "bca", "");
+ // don't strip wrong end
+ LSTRIP_TEST("abc", "c", "abc");
+ LSTRIP_TEST("abca", "a", "bca");
+ RSTRIP_TEST("abc", "a", "abc");
+ RSTRIP_TEST("abca", "a", "abc");
+ // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
+ // and the same second as "ÿ" (\u00ff)
+ LSTRIP_UTF8_TEST("¿", "µÿ", "¿");
+ RSTRIP_UTF8_TEST("¿", "µÿ", "¿");
+ LSTRIP_UTF8_TEST("µ¿ÿ", "µÿ", "¿ÿ");
+ RSTRIP_UTF8_TEST("µ¿ÿ", "µÿ", "µ¿");
+
+ // the above tests repeated with additional superfluous strip chars
+
+ // strip none
+ LSTRIP_TEST("abc", "qwjkl", "abc");
+ RSTRIP_TEST("abc", "qwjkl", "abc");
+ // strip one
+ LSTRIP_TEST("abc", "qwajkl", "bc");
+ RSTRIP_TEST("abc", "qwcjkl", "ab");
+ // strip lots
+ LSTRIP_TEST("bababbababccc", "qwabjkl", "ccc");
+ RSTRIP_TEST("aaabcbcbcbbcbbc", "qwcbjkl", "aaa");
+ // strip empty string
+ LSTRIP_TEST("", "qwjkl", "");
+ RSTRIP_TEST("", "qwjkl", "");
+ // strip to empty string
+ LSTRIP_TEST("abcabcabc", "qwbcajkl", "");
+ RSTRIP_TEST("abcabcabc", "qwbcajkl", "");
+ // don't strip wrong end
+ LSTRIP_TEST("abc", "qwcjkl", "abc");
+ LSTRIP_TEST("abca", "qwajkl", "bca");
+ RSTRIP_TEST("abc", "qwajkl", "abc");
+ RSTRIP_TEST("abca", "qwajkl", "abc");
+ // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
+ // and the same second as "ÿ" (\u00ff)
+ LSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿");
+ RSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿");
+ LSTRIP_UTF8_TEST("µ¿ÿ", "qwaµÿjkl", "¿ÿ");
+ RSTRIP_UTF8_TEST("µ¿ÿ", "qwaµÿjkl", "µ¿");
+
+ CHECK(state);
+
+#undef LSTRIP_TEST
+#undef RSTRIP_TEST
+#undef LSTRIP_UTF8_TEST
+#undef RSTRIP_UTF8_TEST
+}
+
+TEST_CASE("[GDNative String] Cyrillic to_lower()") {
+ godot_string upper, lower, test;
+ godot_string_new_with_utf8_chars(&upper, "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ");
+ godot_string_new_with_utf8_chars(&lower, "абвгдеёжзийклмнопрстуфхцчшщъыьэюя");
+
+ test = godot_string_to_lower(&upper);
+
+ CHECK((u32scmp(godot_string_get_data(&test), godot_string_get_data(&lower)) == 0));
+
+ godot_string_destroy(&upper);
+ godot_string_destroy(&lower);
+ godot_string_destroy(&test);
+}
+
+TEST_CASE("[GDNative String] Count and countn functionality") {
+#define COUNT_TEST(x, y, r) \
+ { \
+ godot_string s, t; \
+ godot_string_new_with_latin1_chars(&s, x); \
+ godot_string_new_with_latin1_chars(&t, y); \
+ state = state && (godot_string_count(&s, &t, 0, 0) == r); \
+ godot_string_destroy(&s); \
+ godot_string_destroy(&t); \
+ }
+
+#define COUNTR_TEST(x, y, a, b, r) \
+ { \
+ godot_string s, t; \
+ godot_string_new_with_latin1_chars(&s, x); \
+ godot_string_new_with_latin1_chars(&t, y); \
+ state = state && (godot_string_count(&s, &t, a, b) == r); \
+ godot_string_destroy(&s); \
+ godot_string_destroy(&t); \
+ }
+
+#define COUNTN_TEST(x, y, r) \
+ { \
+ godot_string s, t; \
+ godot_string_new_with_latin1_chars(&s, x); \
+ godot_string_new_with_latin1_chars(&t, y); \
+ state = state && (godot_string_countn(&s, &t, 0, 0) == r); \
+ godot_string_destroy(&s); \
+ godot_string_destroy(&t); \
+ }
+
+#define COUNTNR_TEST(x, y, a, b, r) \
+ { \
+ godot_string s, t; \
+ godot_string_new_with_latin1_chars(&s, x); \
+ godot_string_new_with_latin1_chars(&t, y); \
+ state = state && (godot_string_countn(&s, &t, a, b) == r); \
+ godot_string_destroy(&s); \
+ godot_string_destroy(&t); \
+ }
+ bool state = true;
+
+ COUNT_TEST("", "Test", 0);
+ COUNT_TEST("Test", "", 0);
+ COUNT_TEST("Test", "test", 0);
+ COUNT_TEST("Test", "TEST", 0);
+ COUNT_TEST("TEST", "TEST", 1);
+ COUNT_TEST("Test", "Test", 1);
+ COUNT_TEST("aTest", "Test", 1);
+ COUNT_TEST("Testa", "Test", 1);
+ COUNT_TEST("TestTestTest", "Test", 3);
+ COUNT_TEST("TestTestTest", "TestTest", 1);
+ COUNT_TEST("TestGodotTestGodotTestGodot", "Test", 3);
+
+ COUNTR_TEST("TestTestTestTest", "Test", 4, 8, 1);
+ COUNTR_TEST("TestTestTestTest", "Test", 4, 12, 2);
+ COUNTR_TEST("TestTestTestTest", "Test", 4, 16, 3);
+ COUNTR_TEST("TestTestTestTest", "Test", 4, 0, 3);
+
+ COUNTN_TEST("Test", "test", 1);
+ COUNTN_TEST("Test", "TEST", 1);
+ COUNTN_TEST("testTest-Testatest", "tEst", 4);
+ COUNTNR_TEST("testTest-TeStatest", "tEsT", 4, 16, 2);
+
+ CHECK(state);
+
+#undef COUNT_TEST
+#undef COUNTR_TEST
+#undef COUNTN_TEST
+#undef COUNTNR_TEST
+}
+
+TEST_CASE("[GDNative String] Bigrams") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, "abcd");
+ godot_packed_string_array bigr = godot_string_bigrams(&s);
+ godot_string_destroy(&s);
+
+ CHECK(godot_packed_string_array_size(&bigr) == 3);
+
+ t = godot_packed_string_array_get(&bigr, 0);
+ CHECK(u32scmp(godot_string_get_data(&t), U"ab") == 0);
+ godot_string_destroy(&t);
+
+ t = godot_packed_string_array_get(&bigr, 1);
+ CHECK(u32scmp(godot_string_get_data(&t), U"bc") == 0);
+ godot_string_destroy(&t);
+
+ t = godot_packed_string_array_get(&bigr, 2);
+ CHECK(u32scmp(godot_string_get_data(&t), U"cd") == 0);
+ godot_string_destroy(&t);
+
+ godot_packed_string_array_destroy(&bigr);
+}
+
+TEST_CASE("[GDNative String] c-escape/unescape") {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, "\\1\a2\b\f3\n45\r6\t7\v8\'9\?0\"");
+ godot_string t = godot_string_c_escape(&s);
+ godot_string u = godot_string_c_unescape(&t);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] dedent") {
+ godot_string s, t;
+ godot_string_new_with_latin1_chars(&s, " aaa\n bbb");
+ godot_string_new_with_latin1_chars(&t, "aaa\nbbb");
+ godot_string u = godot_string_dedent(&s);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Path functions") {
+ static const char *path[4] = { "C:\\Godot\\project\\test.tscn", "/Godot/project/test.xscn", "../Godot/project/test.scn", "Godot\\test.doc" };
+ static const char *base_dir[4] = { "C:\\Godot\\project", "/Godot/project", "../Godot/project", "Godot" };
+ static const char *base_name[4] = { "C:\\Godot\\project\\test", "/Godot/project/test", "../Godot/project/test", "Godot\\test" };
+ static const char *ext[4] = { "tscn", "xscn", "scn", "doc" };
+ static const char *file[4] = { "test.tscn", "test.xscn", "test.scn", "test.doc" };
+ static const bool abs[4] = { true, true, false, false };
+
+ for (int i = 0; i < 4; i++) {
+ godot_string s, t, u, f;
+ godot_string_new_with_latin1_chars(&s, path[i]);
+
+ t = godot_string_get_base_dir(&s);
+ godot_string_new_with_latin1_chars(&u, base_dir[i]);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ t = godot_string_get_basename(&s);
+ godot_string_new_with_latin1_chars(&u, base_name[i]);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ t = godot_string_get_extension(&s);
+ godot_string_new_with_latin1_chars(&u, ext[i]);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ t = godot_string_get_file(&s);
+ godot_string_new_with_latin1_chars(&u, file[i]);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string s_simp;
+ s_simp = godot_string_simplify_path(&s);
+ t = godot_string_get_base_dir(&s_simp);
+ godot_string_new_with_latin1_chars(&u, file[i]);
+ f = godot_string_plus_file(&t, &u);
+ CHECK(u32scmp(godot_string_get_data(&f), godot_string_get_data(&s_simp)) == 0);
+ godot_string_destroy(&f);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+ godot_string_destroy(&s_simp);
+
+ CHECK(godot_string_is_abs_path(&s) == abs[i]);
+ CHECK(godot_string_is_rel_path(&s) != abs[i]);
+
+ godot_string_destroy(&s);
+ }
+
+ static const char *file_name[3] = { "test.tscn", "test://.xscn", "?tes*t.scn" };
+ static const bool valid[3] = { true, false, false };
+ for (int i = 0; i < 3; i++) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, file_name[i]);
+ CHECK(godot_string_is_valid_filename(&s) == valid[i]);
+ godot_string_destroy(&s);
+ }
+}
+
+TEST_CASE("[GDNative String] hash") {
+ godot_string a, b, c;
+ godot_string_new_with_latin1_chars(&a, "Test");
+ godot_string_new_with_latin1_chars(&b, "Test");
+ godot_string_new_with_latin1_chars(&c, "West");
+ CHECK(godot_string_hash(&a) == godot_string_hash(&b));
+ CHECK(godot_string_hash(&a) != godot_string_hash(&c));
+
+ CHECK(godot_string_hash64(&a) == godot_string_hash64(&b));
+ CHECK(godot_string_hash64(&a) != godot_string_hash64(&c));
+
+ godot_string_destroy(&a);
+ godot_string_destroy(&b);
+ godot_string_destroy(&c);
+}
+
+TEST_CASE("[GDNative String] http_escape/unescape") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'");
+ godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3A%27docs%27");
+
+ u = godot_string_http_escape(&s);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+
+ u = godot_string_http_unescape(&t);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] percent_encode/decode") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'");
+ godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3a%27docs%27");
+
+ u = godot_string_percent_encode(&s);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+
+ u = godot_string_percent_decode(&t);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] xml_escape/unescape") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "\"Test\" <test@test&'test'>");
+
+ t = godot_string_xml_escape_with_quotes(&s);
+ u = godot_string_xml_unescape(&t);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ t = godot_string_xml_escape(&s);
+ u = godot_string_xml_unescape(&t);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Strip escapes") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "\t\tTest Test\r\n Test");
+ godot_string_new_with_latin1_chars(&t, "Test Test Test");
+
+ u = godot_string_strip_escapes(&s);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+
+ godot_string_destroy(&t);
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Strip edges") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "\t Test Test ");
+
+ godot_string_new_with_latin1_chars(&t, "Test Test ");
+ u = godot_string_strip_edges(&s, true, false);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "\t Test Test");
+ u = godot_string_strip_edges(&s, false, true);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "Test Test");
+ u = godot_string_strip_edges(&s, true, true);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Similarity") {
+ godot_string a, b, c;
+ godot_string_new_with_latin1_chars(&a, "Test");
+ godot_string_new_with_latin1_chars(&b, "West");
+ godot_string_new_with_latin1_chars(&c, "Toad");
+
+ CHECK(godot_string_similarity(&a, &b) > godot_string_similarity(&a, &c));
+
+ godot_string_destroy(&a);
+ godot_string_destroy(&b);
+ godot_string_destroy(&c);
+}
+
+TEST_CASE("[GDNative String] Trim") {
+ godot_string s, t, u, p;
+ godot_string_new_with_latin1_chars(&s, "aaaTestbbb");
+
+ godot_string_new_with_latin1_chars(&p, "aaa");
+ godot_string_new_with_latin1_chars(&t, "Testbbb");
+ u = godot_string_trim_prefix(&s, &p);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+ godot_string_destroy(&p);
+
+ godot_string_new_with_latin1_chars(&p, "bbb");
+ godot_string_new_with_latin1_chars(&t, "aaaTest");
+ u = godot_string_trim_suffix(&s, &p);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+ godot_string_destroy(&p);
+
+ godot_string_new_with_latin1_chars(&p, "Test");
+ u = godot_string_trim_suffix(&s, &p);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&p);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Right/Left") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, "aaaTestbbb");
+ // ^
+
+ godot_string_new_with_latin1_chars(&t, "tbbb");
+ u = godot_string_right(&s, 6);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&t, "aaaTes");
+ u = godot_string_left(&s, 6);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+}
+
+TEST_CASE("[GDNative String] Repeat") {
+ godot_string t, u;
+ godot_string_new_with_latin1_chars(&t, "ab");
+
+ u = godot_string_repeat(&t, 4);
+ CHECK(u32scmp(godot_string_get_data(&u), U"abababab") == 0);
+ godot_string_destroy(&u);
+
+ godot_string_destroy(&t);
+}
+
+TEST_CASE("[GDNative String] SHA1/SHA256/MD5") {
+ godot_string s, t, sha1, sha256, md5;
+ godot_string_new_with_latin1_chars(&s, "Godot");
+ godot_string_new_with_latin1_chars(&sha1, "a1e91f39b9fce6a9998b14bdbe2aa2b39dc2d201");
+ static uint8_t sha1_buf[20] = {
+ 0xA1, 0xE9, 0x1F, 0x39, 0xB9, 0xFC, 0xE6, 0xA9, 0x99, 0x8B, 0x14, 0xBD, 0xBE, 0x2A, 0xA2, 0xB3,
+ 0x9D, 0xC2, 0xD2, 0x01
+ };
+ godot_string_new_with_latin1_chars(&sha256, "2a02b2443f7985d89d09001086ae3dcfa6eb0f55c6ef170715d42328e16e6cb8");
+ static uint8_t sha256_buf[32] = {
+ 0x2A, 0x02, 0xB2, 0x44, 0x3F, 0x79, 0x85, 0xD8, 0x9D, 0x09, 0x00, 0x10, 0x86, 0xAE, 0x3D, 0xCF,
+ 0xA6, 0xEB, 0x0F, 0x55, 0xC6, 0xEF, 0x17, 0x07, 0x15, 0xD4, 0x23, 0x28, 0xE1, 0x6E, 0x6C, 0xB8
+ };
+ godot_string_new_with_latin1_chars(&md5, "4a336d087aeb0390da10ee2ea7cb87f8");
+ static uint8_t md5_buf[16] = {
+ 0x4A, 0x33, 0x6D, 0x08, 0x7A, 0xEB, 0x03, 0x90, 0xDA, 0x10, 0xEE, 0x2E, 0xA7, 0xCB, 0x87, 0xF8
+ };
+
+ godot_packed_byte_array buf = godot_string_sha1_buffer(&s);
+ CHECK(memcmp(sha1_buf, godot_packed_byte_array_ptr(&buf), 20) == 0);
+ godot_packed_byte_array_destroy(&buf);
+
+ t = godot_string_sha1_text(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha1)) == 0);
+ godot_string_destroy(&t);
+
+ buf = godot_string_sha256_buffer(&s);
+ CHECK(memcmp(sha256_buf, godot_packed_byte_array_ptr(&buf), 32) == 0);
+ godot_packed_byte_array_destroy(&buf);
+
+ t = godot_string_sha256_text(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha256)) == 0);
+ godot_string_destroy(&t);
+
+ buf = godot_string_md5_buffer(&s);
+ CHECK(memcmp(md5_buf, godot_packed_byte_array_ptr(&buf), 16) == 0);
+ godot_packed_byte_array_destroy(&buf);
+
+ t = godot_string_md5_text(&s);
+ CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&md5)) == 0);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+ godot_string_destroy(&sha1);
+ godot_string_destroy(&sha256);
+ godot_string_destroy(&md5);
+}
+
+TEST_CASE("[GDNative String] Join") {
+ godot_string s, t, u;
+ godot_string_new_with_latin1_chars(&s, ", ");
+
+ godot_packed_string_array parts;
+ godot_packed_string_array_new(&parts);
+ godot_string_new_with_latin1_chars(&t, "One");
+ godot_packed_string_array_push_back(&parts, &t);
+ godot_string_destroy(&t);
+ godot_string_new_with_latin1_chars(&t, "B");
+ godot_packed_string_array_push_back(&parts, &t);
+ godot_string_destroy(&t);
+ godot_string_new_with_latin1_chars(&t, "C");
+ godot_packed_string_array_push_back(&parts, &t);
+ godot_string_destroy(&t);
+
+ godot_string_new_with_latin1_chars(&u, "One, B, C");
+ t = godot_string_join(&s, &parts);
+ CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
+ godot_string_destroy(&u);
+ godot_string_destroy(&t);
+
+ godot_string_destroy(&s);
+ godot_packed_string_array_destroy(&parts);
+}
+
+TEST_CASE("[GDNative String] Is_*") {
+ static const char *data[12] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1" };
+ static bool isnum[12] = { true, true, true, false, false, false, false, false, false, false, false, false };
+ static bool isint[12] = { true, true, false, false, false, false, false, false, false, false, false, false };
+ static bool ishex[12] = { true, true, false, false, true, false, true, false, true, false, false, false };
+ static bool ishex_p[12] = { false, false, false, false, false, false, false, true, false, false, false, false };
+ static bool isflt[12] = { true, true, true, false, true, true, false, false, false, false, false, false };
+ static bool isid[12] = { false, false, false, false, false, false, false, false, true, true, false, false };
+
+ for (int i = 0; i < 12; i++) {
+ godot_string s;
+ godot_string_new_with_latin1_chars(&s, data[i]);
+ CHECK(godot_string_is_numeric(&s) == isnum[i]);
+ CHECK(godot_string_is_valid_integer(&s) == isint[i]);
+ CHECK(godot_string_is_valid_hex_number(&s, false) == ishex[i]);
+ CHECK(godot_string_is_valid_hex_number(&s, true) == ishex_p[i]);
+ CHECK(godot_string_is_valid_float(&s) == isflt[i]);
+ CHECK(godot_string_is_valid_identifier(&s) == isid[i]);
+ godot_string_destroy(&s);
+ }
+}
+
+TEST_CASE("[GDNative String] humanize_size") {
+ godot_string s;
+
+ s = godot_string_humanize_size(1000);
+ CHECK(u32scmp(godot_string_get_data(&s), U"1000 B") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_humanize_size(1025);
+ CHECK(u32scmp(godot_string_get_data(&s), U"1.00 KiB") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_humanize_size(1025300);
+ CHECK(u32scmp(godot_string_get_data(&s), U"1001.2 KiB") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_humanize_size(100523550);
+ CHECK(u32scmp(godot_string_get_data(&s), U"95.86 MiB") == 0);
+ godot_string_destroy(&s);
+
+ s = godot_string_humanize_size(5345555000);
+ CHECK(u32scmp(godot_string_get_data(&s), U"4.97 GiB") == 0);
+ godot_string_destroy(&s);
+}
+
+} // namespace TestGDNativeString
+
+#endif // TEST_GDNATIVE_STRING_H
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index e58a1d8edc..5c8cbdf869 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -17,3 +17,7 @@ if env["tools"]:
# 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"])
+
+if env["tests"]:
+ env_gdscript.Append(CPPDEFINES=["TESTS_ENABLED"])
+ env_gdscript.add_source_files(env.modules_sources, "./tests/*.cpp")
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 9e40a69712..613039754f 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -167,6 +167,7 @@
i = ceil(1.45) # i is 2
i = ceil(1.001) # i is 2
[/codeblock]
+ See also [method floor], [method round], and [method stepify].
</description>
</method>
<method name="char">
@@ -338,6 +339,7 @@
# a is -3.0
a = floor(-2.99)
[/codeblock]
+ See also [method ceil], [method round], and [method stepify].
[b]Note:[/b] This method returns a float. If you need an integer, you can use [code]int(s)[/code] directly.
</description>
</method>
@@ -367,24 +369,19 @@
<description>
Returns the floating-point modulus of [code]a/b[/code] that wraps equally in positive and negative.
[codeblock]
- var i = -6
- while i &lt; 5:
- prints(i, fposmod(i, 3))
- i += 1
+ for i in 7:
+ var x = 0.5 * i - 1.5
+ print("%4.1f %4.1f %4.1f" % [x, fmod(x, 1.5), fposmod(x, 1.5)])
[/codeblock]
Produces:
[codeblock]
- -6 0
- -5 1
- -4 2
- -3 0
- -2 1
- -1 2
- 0 0
- 1 1
- 2 2
- 3 0
- 4 1
+ -1.5 -0.0 0.0
+ -1.0 -1.0 0.5
+ -0.5 -0.5 1.0
+ 0.0 0.0 0.0
+ 0.5 0.5 0.5
+ 1.0 1.0 1.0
+ 1.5 0.0 0.0
[/codeblock]
</description>
</method>
@@ -769,24 +766,18 @@
<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
+ for i in range(-3, 4):
+ print("%2.0f %2.0f %2.0f" % [i, i % 3, posmod(i, 3)])
[/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
+ -3 0 0
+ -2 -2 1
+ -1 -1 2
+ 0 0 0
+ 1 1 1
+ 2 2 2
+ 3 0 0
[/codeblock]
</description>
</method>
@@ -827,6 +818,7 @@
a = [1, 2, 3]
print("a", "b", a) # Prints ab[1, 2, 3]
[/codeblock]
+ [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed.
</description>
</method>
<method name="print_debug" qualifiers="vararg">
@@ -900,6 +892,7 @@
[codeblock]
push_error("test error") # Prints "test error" to debugger and terminal as error call
[/codeblock]
+ [b]Note:[/b] Errors printed this way will not pause project execution. To print an error message and pause project execution in debug builds, use [code]assert(false, "test error")[/code] instead.
</description>
</method>
<method name="push_warning">
@@ -989,27 +982,15 @@
<description>
Returns an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment).
[codeblock]
- for i in range(4):
- print(i)
- for i in range(2, 5):
- print(i)
- for i in range(0, 6, 2):
- print(i)
+ print(range(4))
+ print(range(2, 5))
+ print(range(0, 6, 2))
[/codeblock]
Output:
[codeblock]
- 0
- 1
- 2
- 3
-
- 2
- 3
- 4
-
- 0
- 2
- 4
+ [0, 1, 2, 3]
+ [2, 3, 4]
+ [0, 2, 4]
[/codeblock]
</description>
</method>
@@ -1043,6 +1024,7 @@
[codeblock]
round(2.6) # Returns 3
[/codeblock]
+ See also [method floor], [method ceil], and [method stepify].
</description>
</method>
<method name="seed">
@@ -1161,6 +1143,7 @@
stepify(100, 32) # Returns 96
stepify(3.14159, 0.01) # Returns 3.14
[/codeblock]
+ See also [method ceil], [method floor], and [method round].
</description>
</method>
<method name="str" qualifiers="vararg">
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index 62ccb93901..631a102130 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -8,7 +8,7 @@
[method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/index.html</link>
+ <link title="GDScript tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/index.html</link>
</tutorials>
<methods>
<method name="get_as_byte_code" qualifiers="const">
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index ae1f2893f1..9a3273d201 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -33,15 +33,15 @@
#include "../gdscript_tokenizer.h"
#include "editor/editor_settings.h"
-static bool _is_char(CharType c) {
+static bool _is_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
-static bool _is_hex_symbol(CharType c) {
+static bool _is_hex_symbol(char32_t c) {
return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
-static bool _is_bin_symbol(CharType c) {
+static bool _is_bin_symbol(char32_t c) {
return (c == '0' || c == '1');
}
@@ -119,7 +119,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
/* search the line */
bool match = true;
- const CharType *start_key = color_regions[c].start_key.c_str();
+ const char32_t *start_key = color_regions[c].start_key.get_data();
for (int k = 0; k < start_key_length; k++) {
if (start_key[k] != str[from + k]) {
match = false;
@@ -153,18 +153,16 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
/* if we are in one find the end key */
if (in_region != -1) {
- /* check there is enough room */
- int chars_left = line_length - from;
- int end_key_length = color_regions[in_region].end_key.length();
- if (chars_left < end_key_length) {
- continue;
- }
-
/* search the line */
int region_end_index = -1;
- const CharType *end_key = color_regions[in_region].start_key.c_str();
+ int end_key_length = color_regions[in_region].end_key.length();
+ const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
- if (!is_a_symbol) {
+ if (line_length - from < end_key_length) {
+ break;
+ }
+
+ if (!is_symbol(str[from])) {
continue;
}
@@ -173,9 +171,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
continue;
}
+ region_end_index = from;
for (int k = 0; k < end_key_length; k++) {
- if (end_key[k] == str[from + k]) {
- region_end_index = from;
+ if (end_key[k] != str[from + k]) {
+ region_end_index = -1;
break;
}
}
@@ -192,7 +191,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
previous_type = REGION;
previous_text = "";
previous_column = j;
- j = from;
+ j = from + (end_key_length - 1);
if (region_end_index == -1) {
color_region_cache[p_line] = in_region;
}
@@ -572,8 +571,12 @@ void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, cons
}
}
+ int at = 0;
for (int i = 0; i < color_regions.size(); i++) {
ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "color region with start key '" + p_start_key + "' already exists.");
+ if (p_start_key.length() < color_regions[i].start_key.length()) {
+ at++;
+ }
}
ColorRegion color_region;
@@ -581,7 +584,8 @@ void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, cons
color_region.start_key = p_start_key;
color_region.end_key = p_end_key;
color_region.line_only = p_line_only;
- color_regions.push_back(color_region);
+ color_regions.insert(at, color_region);
+ clear_highlighting_cache();
}
Ref<EditorSyntaxHighlighter> GDScriptSyntaxHighlighter::_create() const {
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 0263e32c5b..3519038ae6 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1053,7 +1053,9 @@ GDScript::~GDScript() {
memdelete(E->get());
}
- GDScriptCache::remove_script(get_path());
+ if (GDScriptCache::singleton) { // Cache may have been already destroyed at engine shutdown.
+ GDScriptCache::remove_script(get_path());
+ }
_save_orphaned_subclasses();
@@ -2035,7 +2037,33 @@ GDScriptLanguage::~GDScriptLanguage() {
if (_call_stack) {
memdelete_arr(_call_stack);
}
- singleton = nullptr;
+
+ // Clear dependencies between scripts, to ensure cyclic references are broken (to avoid leaks at exit).
+ SelfList<GDScript> *s = script_list.first();
+ while (s) {
+ GDScript *script = s->self();
+ // This ensures the current script is not released before we can check what's the next one
+ // in the list (we can't get the next upfront because we don't know if the reference breaking
+ // will cause it -or any other after it, for that matter- to be released so the next one
+ // is not the same as before).
+ script->reference();
+
+ for (Map<StringName, GDScriptFunction *>::Element *E = script->member_functions.front(); E; E = E->next()) {
+ GDScriptFunction *func = E->get();
+ for (int i = 0; i < func->argument_types.size(); i++) {
+ func->argument_types.write[i].script_type_ref = Ref<Script>();
+ }
+ func->return_type.script_type_ref = Ref<Script>();
+ }
+ for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) {
+ E->get().data_type.script_type_ref = Ref<Script>();
+ }
+
+ s = s->next();
+ script->unreference();
+ }
+
+ singleton = NULL;
}
void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass) {
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index cabe096579..943a49060f 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -213,6 +213,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
return err;
}
+ base = parser->get_parser()->head->get_datatype();
}
} else if (ProjectSettings::get_singleton()->has_autoload(name) && ProjectSettings::get_singleton()->get_autoload(name).is_singleton) {
const ProjectSettings::AutoloadInfo &info = ProjectSettings::get_singleton()->get_autoload(name);
@@ -504,6 +505,9 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
member.variable->set_datatype(datatype); // Allow recursive usage.
reduce_expression(member.variable->initializer);
datatype = member.variable->initializer->get_datatype();
+ if (datatype.type_source != GDScriptParser::DataType::UNDETECTED) {
+ datatype.type_source = GDScriptParser::DataType::INFERRED;
+ }
}
if (member.variable->datatype_specifier != nullptr) {
@@ -539,6 +543,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
} else if (datatype.builtin_type == Variant::NIL) {
push_error(vformat(R"(Cannot infer the type of "%s" variable because the initial value is "null".)", member.variable->identifier->name), member.variable->initializer);
}
+ datatype.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
}
datatype.is_constant = false;
@@ -789,7 +794,7 @@ void GDScriptAnalyzer::resolve_node(GDScriptParser::Node *p_node) {
resolve_match_branch(static_cast<GDScriptParser::MatchBranchNode *>(p_node), nullptr);
break;
case GDScriptParser::Node::PARAMETER:
- resolve_pararameter(static_cast<GDScriptParser::ParameterNode *>(p_node));
+ resolve_parameter(static_cast<GDScriptParser::ParameterNode *>(p_node));
break;
case GDScriptParser::Node::PATTERN:
resolve_match_pattern(static_cast<GDScriptParser::PatternNode *>(p_node), nullptr);
@@ -843,7 +848,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
parser->current_function = p_function;
for (int i = 0; i < p_function->parameters.size(); i++) {
- resolve_pararameter(p_function->parameters[i]);
+ resolve_parameter(p_function->parameters[i]);
#ifdef DEBUG_ENABLED
if (p_function->parameters[i]->usages == 0 && !String(p_function->parameters[i]->identifier->name).begins_with("_")) {
parser->push_warning(p_function->parameters[i]->identifier, GDScriptWarning::UNUSED_PARAMETER, p_function->identifier->name, p_function->parameters[i]->identifier->name);
@@ -913,6 +918,7 @@ void GDScriptAnalyzer::decide_suite_type(GDScriptParser::Node *p_suite, GDScript
p_suite->datatype.type_source = GDScriptParser::DataType::UNDETECTED;
} else {
p_suite->set_datatype(p_statement->get_datatype());
+ p_suite->datatype.type_source = GDScriptParser::DataType::INFERRED;
}
break;
default:
@@ -1258,14 +1264,19 @@ void GDScriptAnalyzer::resolve_match_pattern(GDScriptParser::PatternNode *p_matc
p_match_pattern->set_datatype(result);
}
-void GDScriptAnalyzer::resolve_pararameter(GDScriptParser::ParameterNode *p_parameter) {
+void GDScriptAnalyzer::resolve_parameter(GDScriptParser::ParameterNode *p_parameter) {
GDScriptParser::DataType result;
result.kind = GDScriptParser::DataType::VARIANT;
if (p_parameter->default_value != nullptr) {
reduce_expression(p_parameter->default_value);
result = p_parameter->default_value->get_datatype();
- result.type_source = GDScriptParser::DataType::INFERRED;
+ if (p_parameter->infer_datatype) {
+ result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
+ } else {
+ result.type_source = GDScriptParser::DataType::INFERRED;
+ }
+ result.is_constant = false;
}
if (p_parameter->datatype_specifier != nullptr) {
@@ -1275,7 +1286,7 @@ void GDScriptAnalyzer::resolve_pararameter(GDScriptParser::ParameterNode *p_para
if (p_parameter->default_value != nullptr) {
if (!is_type_compatible(result, p_parameter->default_value->get_datatype())) {
- push_error(vformat(R"(Type of default value for parameter "%s" (%s) is not compatible with paremeter type (%s).)", p_parameter->identifier->name, p_parameter->default_value->get_datatype().to_string(), p_parameter->datatype_specifier->get_datatype().to_string()), p_parameter->default_value);
+ push_error(vformat(R"(Type of default value for parameter "%s" (%s) is not compatible with parameter type (%s).)", p_parameter->identifier->name, p_parameter->default_value->get_datatype().to_string(), p_parameter->datatype_specifier->get_datatype().to_string()), p_parameter->default_value);
} else if (p_parameter->default_value->get_datatype().is_variant()) {
mark_node_unsafe(p_parameter);
}
@@ -1455,7 +1466,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
bool compatible = true;
GDScriptParser::DataType op_type = p_assignment->assigned_value->get_datatype();
if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
- op_type = get_operation_type(p_assignment->variant_op, p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), compatible);
+ op_type = get_operation_type(p_assignment->variant_op, p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), compatible, p_assignment->assigned_value);
}
if (compatible) {
@@ -1618,7 +1629,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
ERR_PRINT("Parser bug: unknown binary operation.");
}
}
- p_binary_op->set_datatype(type_from_variant(p_binary_op->reduced_value));
+ p_binary_op->set_datatype(type_from_variant(p_binary_op->reduced_value, p_binary_op));
return;
}
@@ -1632,7 +1643,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
} else {
if (p_binary_op->variant_op < Variant::OP_MAX) {
bool valid = false;
- result = get_operation_type(p_binary_op->variant_op, p_binary_op->left_operand->get_datatype(), right_type, valid);
+ result = get_operation_type(p_binary_op->variant_op, p_binary_op->left_operand->get_datatype(), right_type, valid, p_binary_op);
if (!valid) {
push_error(vformat(R"(Invalid operands "%s" and "%s" for "%s" operator.)", p_binary_op->left_operand->get_datatype().to_string(), right_type.to_string(), Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op);
@@ -2061,23 +2072,37 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
if (valid) {
p_identifier->is_constant = true;
p_identifier->reduced_value = result;
- p_identifier->set_datatype(type_from_variant(result));
+ p_identifier->set_datatype(type_from_variant(result, p_identifier));
} else {
push_error(vformat(R"(Cannot find constant "%s" on type "%s".)", name, base.to_string()), p_identifier);
}
} else {
- Callable::CallError temp;
- Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp);
- List<PropertyInfo> properties;
- dummy.get_property_list(&properties);
- for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) {
- const PropertyInfo &prop = E->get();
- if (prop.name == name) {
- p_identifier->set_datatype(type_from_property(prop));
+ switch (base.builtin_type) {
+ case Variant::NIL: {
+ push_error(vformat(R"(Invalid get index "%s" on base Nil)", name), p_identifier);
return;
}
+ case Variant::DICTIONARY: {
+ GDScriptParser::DataType dummy;
+ dummy.kind = GDScriptParser::DataType::VARIANT;
+ p_identifier->set_datatype(dummy);
+ return;
+ }
+ default: {
+ Callable::CallError temp;
+ Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp);
+ List<PropertyInfo> properties;
+ dummy.get_property_list(&properties);
+ for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) {
+ const PropertyInfo &prop = E->get();
+ if (prop.name == name) {
+ p_identifier->set_datatype(type_from_property(prop));
+ return;
+ }
+ }
+ push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier);
+ }
}
- push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier);
}
return;
}
@@ -2192,7 +2217,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
if (valid) {
p_identifier->is_constant = true;
p_identifier->reduced_value = int_constant;
- p_identifier->set_datatype(type_from_variant(int_constant));
+ p_identifier->set_datatype(type_from_variant(int_constant, p_identifier));
return;
}
}
@@ -2289,10 +2314,34 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
return;
}
+ // Try singletons.
+ // Do this before globals because this might be a singleton loading another one before it's compiled.
+ if (ProjectSettings::get_singleton()->has_autoload(name)) {
+ const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(name);
+ if (autoload.is_singleton) {
+ // Singleton exists, so it's at least a Node.
+ GDScriptParser::DataType result;
+ result.kind = GDScriptParser::DataType::NATIVE;
+ result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+ if (autoload.path.to_lower().ends_with(GDScriptLanguage::get_singleton()->get_extension())) {
+ Ref<GDScriptParserRef> parser = get_parser_for(autoload.path);
+ if (parser.is_valid()) {
+ Error err = parser->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
+ if (err == OK) {
+ result = type_from_metatype(parser->get_parser()->head->get_datatype());
+ }
+ }
+ }
+ result.is_constant = true;
+ p_identifier->set_datatype(result);
+ return;
+ }
+ }
+
if (GDScriptLanguage::get_singleton()->get_global_map().has(name)) {
int idx = GDScriptLanguage::get_singleton()->get_global_map()[name];
Variant constant = GDScriptLanguage::get_singleton()->get_global_array()[idx];
- p_identifier->set_datatype(type_from_variant(constant));
+ p_identifier->set_datatype(type_from_variant(constant, p_identifier));
p_identifier->is_constant = true;
p_identifier->reduced_value = constant;
return;
@@ -2300,7 +2349,7 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(name)) {
Variant constant = GDScriptLanguage::get_singleton()->get_named_globals_map()[name];
- p_identifier->set_datatype(type_from_variant(constant));
+ p_identifier->set_datatype(type_from_variant(constant, p_identifier));
p_identifier->is_constant = true;
p_identifier->reduced_value = constant;
return;
@@ -2322,7 +2371,7 @@ void GDScriptAnalyzer::reduce_literal(GDScriptParser::LiteralNode *p_literal) {
p_literal->reduced_value = p_literal->value;
p_literal->is_constant = true;
- p_literal->set_datatype(type_from_variant(p_literal->reduced_value));
+ p_literal->set_datatype(type_from_variant(p_literal->reduced_value, p_literal));
}
void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
@@ -2359,7 +2408,7 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
p_preload->is_constant = true;
p_preload->reduced_value = p_preload->resource;
- p_preload->set_datatype(type_from_variant(p_preload->reduced_value));
+ p_preload->set_datatype(type_from_variant(p_preload->reduced_value, p_preload));
}
void GDScriptAnalyzer::reduce_self(GDScriptParser::SelfNode *p_self) {
@@ -2408,7 +2457,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
} else {
p_subscript->is_constant = true;
p_subscript->reduced_value = value;
- result_type = type_from_variant(value);
+ result_type = type_from_variant(value, p_subscript);
}
result_type.kind = GDScriptParser::DataType::VARIANT;
} else {
@@ -2448,7 +2497,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
} else {
p_subscript->is_constant = true;
p_subscript->reduced_value = value;
- result_type = type_from_variant(value);
+ result_type = type_from_variant(value, p_subscript);
}
result_type.kind = GDScriptParser::DataType::VARIANT;
} else {
@@ -2672,13 +2721,13 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)
if (p_unary_op->operand->is_constant) {
p_unary_op->is_constant = true;
p_unary_op->reduced_value = Variant::evaluate(p_unary_op->variant_op, p_unary_op->operand->reduced_value, Variant());
- result = type_from_variant(p_unary_op->reduced_value);
+ result = type_from_variant(p_unary_op->reduced_value, p_unary_op);
} else if (p_unary_op->operand->get_datatype().is_variant()) {
result.kind = GDScriptParser::DataType::VARIANT;
mark_node_unsafe(p_unary_op);
} else {
bool valid = false;
- result = get_operation_type(p_unary_op->variant_op, p_unary_op->operand->get_datatype(), p_unary_op->operand->get_datatype(), valid);
+ result = get_operation_type(p_unary_op->variant_op, p_unary_op->operand->get_datatype(), p_unary_op->operand->get_datatype(), valid, p_unary_op);
if (!valid) {
push_error(vformat(R"(Invalid operand of type "%s" for unary operator "%s".)", p_unary_op->operand->get_datatype().to_string(), Variant::get_operator_name(p_unary_op->variant_op)), p_unary_op->operand);
@@ -2688,7 +2737,7 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)
p_unary_op->set_datatype(result);
}
-GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_value) {
+GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_value, const GDScriptParser::Node *p_source) {
GDScriptParser::DataType result;
result.is_constant = true;
result.kind = GDScriptParser::DataType::BUILTIN;
@@ -2710,37 +2759,44 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_va
scr = obj->get_script();
}
if (scr.is_valid()) {
- result.script_type = scr;
- result.script_path = scr->get_path();
- Ref<GDScript> gds = scr;
- if (gds.is_valid()) {
- result.kind = GDScriptParser::DataType::CLASS;
- // This might be an inner class, so we want to get the parser for the root.
- // But still get the inner class from that tree.
- GDScript *current = gds.ptr();
- List<StringName> class_chain;
- while (current->_owner) {
- // Push to front so it's in reverse.
- class_chain.push_front(current->name);
- current = current->_owner;
- }
+ if (scr->is_valid()) {
+ result.script_type = scr;
+ result.script_path = scr->get_path();
+ Ref<GDScript> gds = scr;
+ if (gds.is_valid()) {
+ result.kind = GDScriptParser::DataType::CLASS;
+ // This might be an inner class, so we want to get the parser for the root.
+ // But still get the inner class from that tree.
+ GDScript *current = gds.ptr();
+ List<StringName> class_chain;
+ while (current->_owner) {
+ // Push to front so it's in reverse.
+ class_chain.push_front(current->name);
+ current = current->_owner;
+ }
- Ref<GDScriptParserRef> ref = get_parser_for(current->path);
- ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
+ Ref<GDScriptParserRef> ref = get_parser_for(current->path);
+ ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
- GDScriptParser::ClassNode *found = ref->get_parser()->head;
+ GDScriptParser::ClassNode *found = ref->get_parser()->head;
- // It should be okay to assume this exists, since we have a complete script already.
- for (const List<StringName>::Element *E = class_chain.front(); E; E = E->next()) {
- found = found->get_member(E->get()).m_class;
- }
+ // It should be okay to assume this exists, since we have a complete script already.
+ for (const List<StringName>::Element *E = class_chain.front(); E; E = E->next()) {
+ found = found->get_member(E->get()).m_class;
+ }
- result.class_type = found;
- result.script_path = ref->get_parser()->script_path;
+ result.class_type = found;
+ result.script_path = ref->get_parser()->script_path;
+ } else {
+ result.kind = GDScriptParser::DataType::SCRIPT;
+ }
+ result.native_type = scr->get_instance_base_type();
} else {
- result.kind = GDScriptParser::DataType::SCRIPT;
+ push_error(vformat(R"(Constant value uses script from "%s" which is loaded but not compiled.)", scr->get_path()), p_source);
+ result.kind = GDScriptParser::DataType::VARIANT;
+ result.type_source = GDScriptParser::DataType::UNDETECTED;
+ result.is_meta_type = false;
}
- result.native_type = scr->get_instance_base_type();
} else {
result.kind = GDScriptParser::DataType::NATIVE;
if (result.native_type == GDScriptNativeClass::get_class_static()) {
@@ -2931,7 +2987,7 @@ bool GDScriptAnalyzer::validate_call_arg(const List<GDScriptParser::DataType> &p
if (arg_type.is_variant()) {
// Argument can be anything, so this is unsafe.
mark_node_unsafe(p_call->arguments[i]);
- } else if (!is_type_compatible(par_type, arg_type, true)) {
+ } else if (par_type.is_hard_type() && !is_type_compatible(par_type, arg_type, true)) {
// Supertypes are acceptable for dynamic compliance, but it's unsafe.
mark_node_unsafe(p_call);
if (!is_type_compatible(arg_type, par_type)) {
@@ -2996,7 +3052,7 @@ bool GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_local, con
}
#endif
-GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid) {
+GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source) {
// This function creates dummy variant values and apply the operation to those. Less error-prone than keeping a table of valid operations.
GDScriptParser::DataType result;
@@ -3069,7 +3125,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
Variant::evaluate(p_operation, a, b, ret, r_valid);
if (r_valid) {
- return type_from_variant(ret);
+ return type_from_variant(ret, p_source);
}
return result;
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index da767522ad..c3911cce76 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -67,7 +67,7 @@ class GDScriptAnalyzer {
void resolve_match(GDScriptParser::MatchNode *p_match);
void resolve_match_branch(GDScriptParser::MatchBranchNode *p_match_branch, GDScriptParser::ExpressionNode *p_match_test);
void resolve_match_pattern(GDScriptParser::PatternNode *p_match_pattern, GDScriptParser::ExpressionNode *p_match_test);
- void resolve_pararameter(GDScriptParser::ParameterNode *p_parameter);
+ void resolve_parameter(GDScriptParser::ParameterNode *p_parameter);
void resolve_return(GDScriptParser::ReturnNode *p_return);
// Reduction functions.
@@ -90,7 +90,7 @@ class GDScriptAnalyzer {
void reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op);
// Helpers.
- GDScriptParser::DataType type_from_variant(const Variant &p_value);
+ GDScriptParser::DataType type_from_variant(const Variant &p_value, const GDScriptParser::Node *p_source);
GDScriptParser::DataType type_from_metatype(const GDScriptParser::DataType &p_meta_type) const;
GDScriptParser::DataType type_from_property(const PropertyInfo &p_property) const;
GDScriptParser::DataType make_global_class_meta_type(const StringName &p_class_name);
@@ -98,7 +98,7 @@ class GDScriptAnalyzer {
bool function_signature_from_info(const MethodInfo &p_info, GDScriptParser::DataType &r_return_type, List<GDScriptParser::DataType> &r_par_types, int &r_default_arg_count, bool &r_static, bool &r_vararg);
bool validate_call_arg(const List<GDScriptParser::DataType> &p_par_types, int p_default_args_count, bool p_is_vararg, const GDScriptParser::CallNode *p_call);
bool validate_call_arg(const MethodInfo &p_method, const GDScriptParser::CallNode *p_call);
- GDScriptParser::DataType get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid);
+ GDScriptParser::DataType get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source);
bool is_type_compatible(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion = false) const;
void push_error(const String &p_message, const GDScriptParser::Node *p_origin);
void mark_node_unsafe(const GDScriptParser::Node *p_node);
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
new file mode 100644
index 0000000000..8f0ce99de6
--- /dev/null
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -0,0 +1,736 @@
+/*************************************************************************/
+/* gdscript_byte_codegen.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gdscript_byte_codegen.h"
+
+#include "core/debugger/engine_debugger.h"
+#include "gdscript.h"
+
+uint32_t GDScriptByteCodeGenerator::add_parameter(const StringName &p_name, bool p_is_optional, const GDScriptDataType &p_type) {
+#ifdef TOOLS_ENABLED
+ function->arg_names.push_back(p_name);
+#endif
+ function->_argument_count++;
+ function->argument_types.push_back(p_type);
+ if (p_is_optional) {
+ if (function->_default_arg_count == 0) {
+ append(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT);
+ }
+ function->default_arguments.push_back(opcodes.size());
+ function->_default_arg_count++;
+ }
+
+ return add_local(p_name, p_type);
+}
+
+uint32_t GDScriptByteCodeGenerator::add_local(const StringName &p_name, const GDScriptDataType &p_type) {
+ int stack_pos = increase_stack();
+ add_stack_identifier(p_name, stack_pos);
+ return stack_pos;
+}
+
+uint32_t GDScriptByteCodeGenerator::add_local_constant(const StringName &p_name, const Variant &p_constant) {
+ int index = add_or_get_constant(p_constant);
+ local_constants[p_name] = index;
+ return index;
+}
+
+uint32_t GDScriptByteCodeGenerator::add_or_get_constant(const Variant &p_constant) {
+ if (constant_map.has(p_constant)) {
+ return constant_map[p_constant];
+ }
+ int index = constant_map.size();
+ constant_map[p_constant] = index;
+ return index;
+}
+
+uint32_t GDScriptByteCodeGenerator::add_or_get_name(const StringName &p_name) {
+ return get_name_map_pos(p_name);
+}
+
+uint32_t GDScriptByteCodeGenerator::add_temporary() {
+ current_temporaries++;
+ return increase_stack();
+}
+
+void GDScriptByteCodeGenerator::pop_temporary() {
+ current_stack_size--;
+ current_temporaries--;
+}
+
+void GDScriptByteCodeGenerator::start_parameters() {}
+
+void GDScriptByteCodeGenerator::end_parameters() {
+ function->default_arguments.invert();
+}
+
+void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) {
+ function = memnew(GDScriptFunction);
+ debug_stack = EngineDebugger::is_active();
+
+ function->name = p_function_name;
+ function->_script = p_script;
+ function->source = p_script->get_path();
+
+#ifdef DEBUG_ENABLED
+ function->func_cname = (String(function->source) + " - " + String(p_function_name)).utf8();
+ function->_func_cname = function->func_cname.get_data();
+#endif
+
+ function->_static = p_static;
+ function->return_type = p_return_type;
+ function->rpc_mode = p_rpc_mode;
+ function->_argument_count = 0;
+}
+
+GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
+ append(GDScriptFunction::OPCODE_END);
+
+ if (constant_map.size()) {
+ function->_constant_count = constant_map.size();
+ function->constants.resize(constant_map.size());
+ function->_constants_ptr = function->constants.ptrw();
+ const Variant *K = nullptr;
+ while ((K = constant_map.next(K))) {
+ int idx = constant_map[*K];
+ function->constants.write[idx] = *K;
+ }
+ } else {
+ function->_constants_ptr = nullptr;
+ function->_constant_count = 0;
+ }
+
+ if (name_map.size()) {
+ function->global_names.resize(name_map.size());
+ function->_global_names_ptr = &function->global_names[0];
+ for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
+ function->global_names.write[E->get()] = E->key();
+ }
+ function->_global_names_count = function->global_names.size();
+
+ } else {
+ function->_global_names_ptr = nullptr;
+ function->_global_names_count = 0;
+ }
+
+ if (opcodes.size()) {
+ function->code = opcodes;
+ function->_code_ptr = &function->code[0];
+ function->_code_size = opcodes.size();
+
+ } else {
+ function->_code_ptr = nullptr;
+ function->_code_size = 0;
+ }
+
+ if (function->default_arguments.size()) {
+ function->_default_arg_count = function->default_arguments.size();
+ function->_default_arg_ptr = &function->default_arguments[0];
+ } else {
+ function->_default_arg_count = 0;
+ function->_default_arg_ptr = nullptr;
+ }
+
+ if (debug_stack) {
+ function->stack_debug = stack_debug;
+ }
+ function->_stack_size = stack_max;
+ function->_call_size = call_max;
+
+ ended = true;
+ return function;
+}
+
+#ifdef DEBUG_ENABLED
+void GDScriptByteCodeGenerator::set_signature(const String &p_signature) {
+ function->profile.signature = p_signature;
+}
+#endif
+
+void GDScriptByteCodeGenerator::set_initial_line(int p_line) {
+ function->_initial_line = p_line;
+}
+
+void GDScriptByteCodeGenerator::write_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) {
+ append(GDScriptFunction::OPCODE_OPERATOR);
+ append(p_operator);
+ append(p_left_operand);
+ append(p_right_operand);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_type_test(const Address &p_target, const Address &p_source, const Address &p_type) {
+ append(GDScriptFunction::OPCODE_EXTENDS_TEST);
+ append(p_source);
+ append(p_type);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_type_test_builtin(const Address &p_target, const Address &p_source, Variant::Type p_type) {
+ append(GDScriptFunction::OPCODE_IS_BUILTIN);
+ append(p_source);
+ append(p_type);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_and_left_operand(const Address &p_left_operand) {
+ append(GDScriptFunction::OPCODE_JUMP_IF_NOT);
+ append(p_left_operand);
+ logic_op_jump_pos1.push_back(opcodes.size());
+ append(0); // Jump target, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_and_right_operand(const Address &p_right_operand) {
+ append(GDScriptFunction::OPCODE_JUMP_IF_NOT);
+ append(p_right_operand);
+ logic_op_jump_pos2.push_back(opcodes.size());
+ append(0); // Jump target, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_end_and(const Address &p_target) {
+ // If here means both operands are true.
+ append(GDScriptFunction::OPCODE_ASSIGN_TRUE);
+ append(p_target);
+ // Jump away from the fail condition.
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(opcodes.size() + 3);
+ // Here it means one of operands is false.
+ patch_jump(logic_op_jump_pos1.back()->get());
+ patch_jump(logic_op_jump_pos2.back()->get());
+ logic_op_jump_pos1.pop_back();
+ logic_op_jump_pos2.pop_back();
+ append(GDScriptFunction::OPCODE_ASSIGN_FALSE);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_or_left_operand(const Address &p_left_operand) {
+ append(GDScriptFunction::OPCODE_JUMP_IF);
+ append(p_left_operand);
+ logic_op_jump_pos1.push_back(opcodes.size());
+ append(0); // Jump target, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_or_right_operand(const Address &p_right_operand) {
+ append(GDScriptFunction::OPCODE_JUMP_IF);
+ append(p_right_operand);
+ logic_op_jump_pos2.push_back(opcodes.size());
+ append(0); // Jump target, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_end_or(const Address &p_target) {
+ // If here means both operands are false.
+ append(GDScriptFunction::OPCODE_ASSIGN_FALSE);
+ append(p_target);
+ // Jump away from the success condition.
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(opcodes.size() + 3);
+ // Here it means one of operands is false.
+ patch_jump(logic_op_jump_pos1.back()->get());
+ patch_jump(logic_op_jump_pos2.back()->get());
+ logic_op_jump_pos1.pop_back();
+ logic_op_jump_pos2.pop_back();
+ append(GDScriptFunction::OPCODE_ASSIGN_TRUE);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_start_ternary(const Address &p_target) {
+ ternary_result.push_back(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_ternary_condition(const Address &p_condition) {
+ append(GDScriptFunction::OPCODE_JUMP_IF_NOT);
+ append(p_condition);
+ ternary_jump_fail_pos.push_back(opcodes.size());
+ append(0); // Jump target, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_ternary_true_expr(const Address &p_expr) {
+ append(GDScriptFunction::OPCODE_ASSIGN);
+ append(ternary_result.back()->get());
+ append(p_expr);
+ // Jump away from the false path.
+ append(GDScriptFunction::OPCODE_JUMP);
+ ternary_jump_skip_pos.push_back(opcodes.size());
+ append(0);
+ // Fail must jump here.
+ patch_jump(ternary_jump_fail_pos.back()->get());
+ ternary_jump_fail_pos.pop_back();
+}
+
+void GDScriptByteCodeGenerator::write_ternary_false_expr(const Address &p_expr) {
+ append(GDScriptFunction::OPCODE_ASSIGN);
+ append(ternary_result.back()->get());
+ append(p_expr);
+}
+
+void GDScriptByteCodeGenerator::write_end_ternary() {
+ patch_jump(ternary_jump_skip_pos.back()->get());
+ ternary_jump_skip_pos.pop_back();
+}
+
+void GDScriptByteCodeGenerator::write_set(const Address &p_target, const Address &p_index, const Address &p_source) {
+ append(GDScriptFunction::OPCODE_SET);
+ append(p_target);
+ append(p_index);
+ append(p_source);
+}
+
+void GDScriptByteCodeGenerator::write_get(const Address &p_target, const Address &p_index, const Address &p_source) {
+ append(GDScriptFunction::OPCODE_GET);
+ append(p_source);
+ append(p_index);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
+ append(GDScriptFunction::OPCODE_SET_NAMED);
+ append(p_target);
+ append(p_name);
+ append(p_source);
+}
+
+void GDScriptByteCodeGenerator::write_get_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
+ append(GDScriptFunction::OPCODE_GET_NAMED);
+ append(p_source);
+ append(p_name);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_set_member(const Address &p_value, const StringName &p_name) {
+ append(GDScriptFunction::OPCODE_SET_MEMBER);
+ append(p_name);
+ append(p_value);
+}
+
+void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const StringName &p_name) {
+ append(GDScriptFunction::OPCODE_GET_MEMBER);
+ append(p_name);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
+ if (p_target.type.has_type && !p_source.type.has_type) {
+ // Typed assignment.
+ switch (p_target.type.kind) {
+ case GDScriptDataType::BUILTIN: {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN);
+ append(p_target.type.builtin_type);
+ append(p_target);
+ append(p_source);
+ } break;
+ case GDScriptDataType::NATIVE: {
+ int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
+ class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE);
+ append(class_idx);
+ append(p_target);
+ append(p_source);
+ } break;
+ case GDScriptDataType::SCRIPT:
+ case GDScriptDataType::GDSCRIPT: {
+ Variant script = p_target.type.script_type;
+ int idx = get_constant_pos(script);
+
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT);
+ append(idx);
+ append(p_target);
+ append(p_source);
+ } break;
+ default: {
+ ERR_PRINT("Compiler bug: unresolved assign.");
+
+ // Shouldn't get here, but fail-safe to a regular assignment
+ append(GDScriptFunction::OPCODE_ASSIGN);
+ append(p_target);
+ append(p_source);
+ }
+ }
+ } else {
+ if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
+ // Need conversion..
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN);
+ append(p_target.type.builtin_type);
+ append(p_target);
+ append(p_source);
+ } else {
+ // Either untyped assignment or already type-checked by the parser
+ append(GDScriptFunction::OPCODE_ASSIGN);
+ append(p_target);
+ append(p_source);
+ }
+ }
+}
+
+void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) {
+ append(GDScriptFunction::OPCODE_ASSIGN_TRUE);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_assign_false(const Address &p_target) {
+ append(GDScriptFunction::OPCODE_ASSIGN_FALSE);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) {
+ switch (p_type.kind) {
+ case GDScriptDataType::BUILTIN: {
+ append(GDScriptFunction::OPCODE_CAST_TO_BUILTIN);
+ append(p_type.builtin_type);
+ } break;
+ case GDScriptDataType::NATIVE: {
+ int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_type.native_type];
+ class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
+ append(GDScriptFunction::OPCODE_CAST_TO_NATIVE);
+ append(class_idx);
+ } break;
+ case GDScriptDataType::SCRIPT:
+ case GDScriptDataType::GDSCRIPT: {
+ Variant script = p_type.script_type;
+ int idx = get_constant_pos(script);
+
+ append(GDScriptFunction::OPCODE_CAST_TO_SCRIPT);
+ append(idx);
+ } break;
+ default: {
+ return;
+ }
+ }
+
+ append(p_source);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
+ append(p_arguments.size());
+ append(p_base);
+ append(p_function_name);
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CALL_SELF_BASE);
+ append(p_function_name);
+ append(p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CALL_ASYNC);
+ append(p_arguments.size());
+ append(p_base);
+ append(p_function_name);
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_builtin(const Address &p_target, GDScriptFunctions::Function p_function, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CALL_BUILT_IN);
+ append(p_function);
+ append(p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) {
+ append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
+ append(p_arguments.size());
+ append(p_base);
+ append(p_method->get_name());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) {
+ append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
+ append(p_arguments.size());
+ append(p_base);
+ append(p_method->get_name());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
+ append(p_arguments.size());
+ append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ append(p_function_name);
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
+ append(p_arguments.size());
+ append(p_base);
+ append(p_function_name);
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ alloc_call(p_arguments.size());
+}
+
+void GDScriptByteCodeGenerator::write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CONSTRUCT);
+ append(p_type);
+ append(p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY);
+ append(p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY);
+ append(p_arguments.size() / 2); // This is number of key-value pairs, so only half of actual arguments.
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_await(const Address &p_target, const Address &p_operand) {
+ append(GDScriptFunction::OPCODE_AWAIT);
+ append(p_operand);
+ append(GDScriptFunction::OPCODE_AWAIT_RESUME);
+ append(p_target);
+}
+
+void GDScriptByteCodeGenerator::write_if(const Address &p_condition) {
+ append(GDScriptFunction::OPCODE_JUMP_IF_NOT);
+ append(p_condition);
+ if_jmp_addrs.push_back(opcodes.size());
+ append(0); // Jump destination, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_else() {
+ append(GDScriptFunction::OPCODE_JUMP); // Jump from true if block;
+ int else_jmp_addr = opcodes.size();
+ append(0); // Jump destination, will be patched.
+
+ patch_jump(if_jmp_addrs.back()->get());
+ if_jmp_addrs.pop_back();
+ if_jmp_addrs.push_back(else_jmp_addr);
+}
+
+void GDScriptByteCodeGenerator::write_endif() {
+ patch_jump(if_jmp_addrs.back()->get());
+ if_jmp_addrs.pop_back();
+}
+
+void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Address &p_list) {
+ int counter_pos = increase_stack() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
+ int container_pos = increase_stack() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
+
+ current_breaks_to_patch.push_back(List<int>());
+
+ // Assign container.
+ append(GDScriptFunction::OPCODE_ASSIGN);
+ append(container_pos);
+ append(p_list);
+
+ // Begin loop.
+ append(GDScriptFunction::OPCODE_ITERATE_BEGIN);
+ append(counter_pos);
+ append(container_pos);
+ for_jmp_addrs.push_back(opcodes.size());
+ append(0); // End of loop address, will be patched.
+ append(p_variable);
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(opcodes.size() + 6); // Skip over 'continue' code.
+
+ // Next iteration.
+ int continue_addr = opcodes.size();
+ continue_addrs.push_back(continue_addr);
+ append(GDScriptFunction::OPCODE_ITERATE);
+ append(counter_pos);
+ append(container_pos);
+ for_jmp_addrs.push_back(opcodes.size());
+ append(0); // Jump destination, will be patched.
+ append(p_variable);
+}
+
+void GDScriptByteCodeGenerator::write_endfor() {
+ // Jump back to loop check.
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(continue_addrs.back()->get());
+ continue_addrs.pop_back();
+
+ // Patch end jumps (two of them).
+ for (int i = 0; i < 2; i++) {
+ patch_jump(for_jmp_addrs.back()->get());
+ for_jmp_addrs.pop_back();
+ }
+
+ // Patch break statements.
+ for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
+ patch_jump(E->get());
+ }
+ current_breaks_to_patch.pop_back();
+
+ current_stack_size -= 2; // Remove loop temporaries.
+}
+
+void GDScriptByteCodeGenerator::start_while_condition() {
+ current_breaks_to_patch.push_back(List<int>());
+ continue_addrs.push_back(opcodes.size());
+}
+
+void GDScriptByteCodeGenerator::write_while(const Address &p_condition) {
+ // Condition check.
+ append(GDScriptFunction::OPCODE_JUMP_IF_NOT);
+ append(p_condition);
+ while_jmp_addrs.push_back(opcodes.size());
+ append(0); // End of loop address, will be patched.
+}
+
+void GDScriptByteCodeGenerator::write_endwhile() {
+ // Jump back to loop check.
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(continue_addrs.back()->get());
+ continue_addrs.pop_back();
+
+ // Patch end jump.
+ patch_jump(while_jmp_addrs.back()->get());
+ while_jmp_addrs.pop_back();
+
+ // Patch break statements.
+ for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
+ patch_jump(E->get());
+ }
+ current_breaks_to_patch.pop_back();
+}
+
+void GDScriptByteCodeGenerator::start_match() {
+ match_continues_to_patch.push_back(List<int>());
+}
+
+void GDScriptByteCodeGenerator::start_match_branch() {
+ // Patch continue statements.
+ for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
+ patch_jump(E->get());
+ }
+ match_continues_to_patch.pop_back();
+ // Start a new list for next branch.
+ match_continues_to_patch.push_back(List<int>());
+}
+
+void GDScriptByteCodeGenerator::end_match() {
+ // Patch continue statements.
+ for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
+ patch_jump(E->get());
+ }
+ match_continues_to_patch.pop_back();
+}
+
+void GDScriptByteCodeGenerator::write_break() {
+ append(GDScriptFunction::OPCODE_JUMP);
+ current_breaks_to_patch.back()->get().push_back(opcodes.size());
+ append(0);
+}
+
+void GDScriptByteCodeGenerator::write_continue() {
+ append(GDScriptFunction::OPCODE_JUMP);
+ append(continue_addrs.back()->get());
+}
+
+void GDScriptByteCodeGenerator::write_continue_match() {
+ append(GDScriptFunction::OPCODE_JUMP);
+ match_continues_to_patch.back()->get().push_back(opcodes.size());
+ append(0);
+}
+
+void GDScriptByteCodeGenerator::write_breakpoint() {
+ append(GDScriptFunction::OPCODE_BREAKPOINT);
+}
+
+void GDScriptByteCodeGenerator::write_newline(int p_line) {
+ append(GDScriptFunction::OPCODE_LINE);
+ append(p_line);
+ current_line = p_line;
+}
+
+void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {
+ append(GDScriptFunction::OPCODE_RETURN);
+ append(p_return_value);
+}
+
+void GDScriptByteCodeGenerator::write_assert(const Address &p_test, const Address &p_message) {
+ append(GDScriptFunction::OPCODE_ASSERT);
+ append(p_test);
+ append(p_message);
+}
+
+void GDScriptByteCodeGenerator::start_block() {
+ push_stack_identifiers();
+}
+
+void GDScriptByteCodeGenerator::end_block() {
+ pop_stack_identifiers();
+}
+
+GDScriptByteCodeGenerator::~GDScriptByteCodeGenerator() {
+ if (!ended && function != nullptr) {
+ memdelete(function);
+ }
+}
diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h
new file mode 100644
index 0000000000..62438b6dd2
--- /dev/null
+++ b/modules/gdscript/gdscript_byte_codegen.h
@@ -0,0 +1,277 @@
+/*************************************************************************/
+/* gdscript_byte_codegen.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GDSCRIPT_BYTE_CODEGEN
+#define GDSCRIPT_BYTE_CODEGEN
+
+#include "gdscript_codegen.h"
+
+class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
+ bool ended = false;
+ GDScriptFunction *function = nullptr;
+ bool debug_stack = false;
+
+ Vector<int> opcodes;
+ List<Map<StringName, int>> stack_id_stack;
+ Map<StringName, int> stack_identifiers;
+ Map<StringName, int> local_constants;
+
+ List<GDScriptFunction::StackDebug> stack_debug;
+ List<Map<StringName, int>> block_identifier_stack;
+ Map<StringName, int> block_identifiers;
+
+ int current_stack_size = 0;
+ int current_temporaries = 0;
+
+ HashMap<Variant, int, VariantHasher, VariantComparator> constant_map;
+ Map<StringName, int> name_map;
+#ifdef TOOLS_ENABLED
+ Vector<StringName> named_globals;
+#endif
+ int current_line = 0;
+ int stack_max = 0;
+ int call_max = 0;
+
+ List<int> if_jmp_addrs; // List since this can be nested.
+ List<int> for_jmp_addrs;
+ List<int> while_jmp_addrs;
+ List<int> continue_addrs;
+
+ // Used to patch jumps with `and` and `or` operators with short-circuit.
+ List<int> logic_op_jump_pos1;
+ List<int> logic_op_jump_pos2;
+
+ List<Address> ternary_result;
+ List<int> ternary_jump_fail_pos;
+ List<int> ternary_jump_skip_pos;
+
+ List<List<int>> current_breaks_to_patch;
+ List<List<int>> match_continues_to_patch;
+
+ void add_stack_identifier(const StringName &p_id, int p_stackpos) {
+ stack_identifiers[p_id] = p_stackpos;
+ if (debug_stack) {
+ block_identifiers[p_id] = p_stackpos;
+ GDScriptFunction::StackDebug sd;
+ sd.added = true;
+ sd.line = current_line;
+ sd.identifier = p_id;
+ sd.pos = p_stackpos;
+ stack_debug.push_back(sd);
+ }
+ }
+
+ void push_stack_identifiers() {
+ stack_id_stack.push_back(stack_identifiers);
+ if (debug_stack) {
+ block_identifier_stack.push_back(block_identifiers);
+ block_identifiers.clear();
+ }
+ }
+
+ void pop_stack_identifiers() {
+ stack_identifiers = stack_id_stack.back()->get();
+ current_stack_size = stack_identifiers.size() + current_temporaries;
+ stack_id_stack.pop_back();
+
+ if (debug_stack) {
+ for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) {
+ GDScriptFunction::StackDebug sd;
+ sd.added = false;
+ sd.identifier = E->key();
+ sd.line = current_line;
+ sd.pos = E->get();
+ stack_debug.push_back(sd);
+ }
+ block_identifiers = block_identifier_stack.back()->get();
+ block_identifier_stack.pop_back();
+ }
+ }
+
+ int get_name_map_pos(const StringName &p_identifier) {
+ int ret;
+ if (!name_map.has(p_identifier)) {
+ ret = name_map.size();
+ name_map[p_identifier] = ret;
+ } else {
+ ret = name_map[p_identifier];
+ }
+ return ret;
+ }
+
+ int get_constant_pos(const Variant &p_constant) {
+ if (constant_map.has(p_constant))
+ return constant_map[p_constant];
+ int pos = constant_map.size();
+ constant_map[p_constant] = pos;
+ return pos;
+ }
+
+ void alloc_stack(int p_level) {
+ if (p_level >= stack_max)
+ stack_max = p_level + 1;
+ }
+
+ void alloc_call(int p_params) {
+ if (p_params >= call_max)
+ call_max = p_params;
+ }
+
+ int increase_stack() {
+ int top = current_stack_size++;
+ alloc_stack(current_stack_size);
+ return top;
+ }
+
+ int address_of(const Address &p_address) {
+ switch (p_address.mode) {
+ case Address::SELF:
+ return GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS;
+ case Address::CLASS:
+ return GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS;
+ case Address::MEMBER:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS);
+ case Address::CLASS_CONSTANT:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS);
+ case Address::LOCAL_CONSTANT:
+ case Address::CONSTANT:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
+ case Address::LOCAL_VARIABLE:
+ case Address::TEMPORARY:
+ case Address::FUNCTION_PARAMETER:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
+ case Address::GLOBAL:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
+ case Address::NAMED_GLOBAL:
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
+ case Address::NIL:
+ return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
+ }
+ return -1; // Unreachable.
+ }
+
+ void append(int code) {
+ opcodes.push_back(code);
+ }
+
+ void append(const Address &p_address) {
+ opcodes.push_back(address_of(p_address));
+ }
+
+ void append(const StringName &p_name) {
+ opcodes.push_back(get_name_map_pos(p_name));
+ }
+
+ void patch_jump(int p_address) {
+ opcodes.write[p_address] = opcodes.size();
+ }
+
+public:
+ virtual uint32_t add_parameter(const StringName &p_name, bool p_is_optional, const GDScriptDataType &p_type) override;
+ virtual uint32_t add_local(const StringName &p_name, const GDScriptDataType &p_type) override;
+ virtual uint32_t add_local_constant(const StringName &p_name, const Variant &p_constant) override;
+ virtual uint32_t add_or_get_constant(const Variant &p_constant) override;
+ virtual uint32_t add_or_get_name(const StringName &p_name) override;
+ virtual uint32_t add_temporary() override;
+ virtual void pop_temporary() override;
+
+ virtual void start_parameters() override;
+ virtual void end_parameters() override;
+
+ virtual void start_block() override;
+ virtual void end_block() override;
+
+ virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) override;
+ virtual GDScriptFunction *write_end() override;
+
+#ifdef DEBUG_ENABLED
+ virtual void set_signature(const String &p_signature) override;
+#endif
+ virtual void set_initial_line(int p_line) override;
+
+ virtual void write_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) override;
+ virtual void write_type_test(const Address &p_target, const Address &p_source, const Address &p_type) override;
+ virtual void write_type_test_builtin(const Address &p_target, const Address &p_source, Variant::Type p_type) override;
+ virtual void write_and_left_operand(const Address &p_left_operand) override;
+ virtual void write_and_right_operand(const Address &p_right_operand) override;
+ virtual void write_end_and(const Address &p_target) override;
+ virtual void write_or_left_operand(const Address &p_left_operand) override;
+ virtual void write_or_right_operand(const Address &p_right_operand) override;
+ virtual void write_end_or(const Address &p_target) override;
+ virtual void write_start_ternary(const Address &p_target) override;
+ virtual void write_ternary_condition(const Address &p_condition) override;
+ virtual void write_ternary_true_expr(const Address &p_expr) override;
+ virtual void write_ternary_false_expr(const Address &p_expr) override;
+ virtual void write_end_ternary() override;
+ virtual void write_set(const Address &p_target, const Address &p_index, const Address &p_source) override;
+ virtual void write_get(const Address &p_target, const Address &p_index, const Address &p_source) override;
+ virtual void write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) override;
+ virtual void write_get_named(const Address &p_target, const StringName &p_name, const Address &p_source) override;
+ virtual void write_set_member(const Address &p_value, const StringName &p_name) override;
+ virtual void write_get_member(const Address &p_target, const StringName &p_name) override;
+ virtual void write_assign(const Address &p_target, const Address &p_source) override;
+ virtual void write_assign_true(const Address &p_target) override;
+ virtual void write_assign_false(const Address &p_target) override;
+ virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) override;
+ virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_call_builtin(const Address &p_target, GDScriptFunctions::Function p_function, const Vector<Address> &p_arguments) override;
+ virtual void write_call_method_bind(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) override;
+ virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) override;
+ virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) override;
+ virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) override;
+ virtual void write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) override;
+ virtual void write_await(const Address &p_target, const Address &p_operand) override;
+ virtual void write_if(const Address &p_condition) override;
+ virtual void write_else() override;
+ virtual void write_endif() override;
+ virtual void write_for(const Address &p_variable, const Address &p_list) override;
+ virtual void write_endfor() override;
+ virtual void start_while_condition() override;
+ virtual void write_while(const Address &p_condition) override;
+ virtual void write_endwhile() override;
+ virtual void start_match() override;
+ virtual void start_match_branch() override;
+ virtual void end_match() override;
+ virtual void write_break() override;
+ virtual void write_continue() override;
+ virtual void write_continue_match() override;
+ virtual void write_breakpoint() override;
+ virtual void write_newline(int p_line) override;
+ virtual void write_return(const Address &p_return_value) override;
+ virtual void write_assert(const Address &p_test, const Address &p_message) override;
+
+ virtual ~GDScriptByteCodeGenerator();
+};
+
+#endif // GDSCRIPT_BYTE_CODEGEN
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 992f8f4b58..57b95f5b21 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -108,20 +108,20 @@ GDScriptParserRef::~GDScriptParserRef() {
if (analyzer != nullptr) {
memdelete(analyzer);
}
- MutexLock(GDScriptCache::singleton->lock);
+ MutexLock lock(GDScriptCache::singleton->lock);
GDScriptCache::singleton->parser_map.erase(path);
}
GDScriptCache *GDScriptCache::singleton = nullptr;
void GDScriptCache::remove_script(const String &p_path) {
- MutexLock(singleton->lock);
+ MutexLock lock(singleton->lock);
singleton->shallow_gdscript_cache.erase(p_path);
singleton->full_gdscript_cache.erase(p_path);
}
Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptParserRef::Status p_status, Error &r_error, const String &p_owner) {
- MutexLock(singleton->lock);
+ MutexLock lock(singleton->lock);
Ref<GDScriptParserRef> ref;
if (p_owner != String()) {
singleton->dependencies[p_owner].insert(p_path);
@@ -168,7 +168,7 @@ String GDScriptCache::get_source_code(const String &p_path) {
}
Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const String &p_owner) {
- MutexLock(singleton->lock);
+ MutexLock lock(singleton->lock);
if (p_owner != String()) {
singleton->dependencies[p_owner].insert(p_path);
}
@@ -190,7 +190,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri
}
Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) {
- MutexLock(singleton->lock);
+ MutexLock lock(singleton->lock);
if (p_owner != String()) {
singleton->dependencies[p_owner].insert(p_path);
diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h
new file mode 100644
index 0000000000..31e1e6ba23
--- /dev/null
+++ b/modules/gdscript/gdscript_codegen.h
@@ -0,0 +1,160 @@
+/*************************************************************************/
+/* gdscript_codegen.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GDSCRIPT_CODEGEN
+#define GDSCRIPT_CODEGEN
+
+#include "core/io/multiplayer_api.h"
+#include "core/string_name.h"
+#include "core/variant.h"
+#include "gdscript_function.h"
+#include "gdscript_functions.h"
+
+class GDScriptCodeGenerator {
+public:
+ struct Address {
+ enum AddressMode {
+ SELF,
+ CLASS,
+ MEMBER,
+ CONSTANT,
+ CLASS_CONSTANT,
+ LOCAL_CONSTANT,
+ LOCAL_VARIABLE,
+ FUNCTION_PARAMETER,
+ TEMPORARY,
+ GLOBAL,
+ NAMED_GLOBAL,
+ NIL,
+ };
+ AddressMode mode = NIL;
+ uint32_t address = 0;
+ GDScriptDataType type;
+
+ Address() {}
+ Address(AddressMode p_mode, const GDScriptDataType &p_type = GDScriptDataType()) {
+ mode = p_mode;
+ type = p_type;
+ }
+ Address(AddressMode p_mode, uint32_t p_address, const GDScriptDataType &p_type = GDScriptDataType()) {
+ mode = p_mode,
+ address = p_address;
+ type = p_type;
+ }
+ };
+
+ virtual uint32_t add_parameter(const StringName &p_name, bool p_is_optional, const GDScriptDataType &p_type) = 0;
+ virtual uint32_t add_local(const StringName &p_name, const GDScriptDataType &p_type) = 0;
+ virtual uint32_t add_local_constant(const StringName &p_name, const Variant &p_constant) = 0;
+ virtual uint32_t add_or_get_constant(const Variant &p_constant) = 0;
+ virtual uint32_t add_or_get_name(const StringName &p_name) = 0;
+ virtual uint32_t add_temporary() = 0;
+ virtual void pop_temporary() = 0;
+
+ virtual void start_parameters() = 0;
+ virtual void end_parameters() = 0;
+
+ virtual void start_block() = 0;
+ virtual void end_block() = 0;
+
+ // virtual int get_max_stack_level() = 0;
+ // virtual int get_max_function_arguments() = 0;
+
+ virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) = 0;
+ virtual GDScriptFunction *write_end() = 0;
+
+#ifdef DEBUG_ENABLED
+ virtual void set_signature(const String &p_signature) = 0;
+#endif
+ virtual void set_initial_line(int p_line) = 0;
+
+ // virtual void alloc_stack(int p_level) = 0; // Is this needed?
+ // virtual void alloc_call(int p_arg_count) = 0; // This might be automatic from other functions.
+
+ virtual void write_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) = 0;
+ virtual void write_type_test(const Address &p_target, const Address &p_source, const Address &p_type) = 0;
+ virtual void write_type_test_builtin(const Address &p_target, const Address &p_source, Variant::Type p_type) = 0;
+ virtual void write_and_left_operand(const Address &p_left_operand) = 0;
+ virtual void write_and_right_operand(const Address &p_right_operand) = 0;
+ virtual void write_end_and(const Address &p_target) = 0;
+ virtual void write_or_left_operand(const Address &p_left_operand) = 0;
+ virtual void write_or_right_operand(const Address &p_right_operand) = 0;
+ virtual void write_end_or(const Address &p_target) = 0;
+ virtual void write_start_ternary(const Address &p_target) = 0;
+ virtual void write_ternary_condition(const Address &p_condition) = 0;
+ virtual void write_ternary_true_expr(const Address &p_expr) = 0;
+ virtual void write_ternary_false_expr(const Address &p_expr) = 0;
+ virtual void write_end_ternary() = 0;
+ virtual void write_set(const Address &p_target, const Address &p_index, const Address &p_source) = 0;
+ virtual void write_get(const Address &p_target, const Address &p_index, const Address &p_source) = 0;
+ virtual void write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) = 0;
+ virtual void write_get_named(const Address &p_target, const StringName &p_name, const Address &p_source) = 0;
+ virtual void write_set_member(const Address &p_value, const StringName &p_name) = 0;
+ virtual void write_get_member(const Address &p_target, const StringName &p_name) = 0;
+ virtual void write_assign(const Address &p_target, const Address &p_source) = 0;
+ virtual void write_assign_true(const Address &p_target) = 0;
+ virtual void write_assign_false(const Address &p_target) = 0;
+ virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) = 0;
+ virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_builtin(const Address &p_target, GDScriptFunctions::Function p_function, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_method_bind(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, const MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) = 0;
+ virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) = 0;
+ virtual void write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) = 0;
+ virtual void write_await(const Address &p_target, const Address &p_operand) = 0;
+ virtual void write_if(const Address &p_condition) = 0;
+ // virtual void write_elseif(const Address &p_condition) = 0; This kind of makes things more difficult for no real benefit.
+ virtual void write_else() = 0;
+ virtual void write_endif() = 0;
+ virtual void write_for(const Address &p_variable, const Address &p_list) = 0;
+ virtual void write_endfor() = 0;
+ virtual void start_while_condition() = 0; // Used to allow a jump to the expression evaluation.
+ virtual void write_while(const Address &p_condition) = 0;
+ virtual void write_endwhile() = 0;
+ virtual void start_match() = 0;
+ virtual void start_match_branch() = 0;
+ virtual void end_match() = 0;
+ virtual void write_break() = 0;
+ virtual void write_continue() = 0;
+ virtual void write_continue_match() = 0;
+ virtual void write_breakpoint() = 0;
+ virtual void write_newline(int p_line) = 0;
+ virtual void write_return(const Address &p_return_value) = 0;
+ virtual void write_assert(const Address &p_test, const Address &p_message) = 0;
+
+ virtual ~GDScriptCodeGenerator() {}
+};
+
+#endif // GDSCRIPT_CODEGEN
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 67a894912f..bad450c9f9 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -31,6 +31,7 @@
#include "gdscript_compiler.h"
#include "gdscript.h"
+#include "gdscript_byte_codegen.h"
#include "gdscript_cache.h"
bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) {
@@ -38,7 +39,7 @@ bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringN
return false;
}
- if (codegen.stack_identifiers.has(p_name)) {
+ if (codegen.locals.has(p_name)) {
return false; //shadowed
}
@@ -75,46 +76,7 @@ void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::N
}
}
-bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::UnaryOpNode *on, Variant::Operator op, int p_stack_level) {
- int src_address_a = _parse_expression(codegen, on->operand, p_stack_level);
- if (src_address_a < 0) {
- return false;
- }
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
- codegen.opcodes.push_back(op); //which operator
- codegen.opcodes.push_back(src_address_a); // argument 1
- codegen.opcodes.push_back(src_address_a); // argument 2 (repeated)
- //codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter)
- return true;
-}
-
-bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_left_operand, const GDScriptParser::ExpressionNode *p_right_operand, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
- int src_address_a = _parse_expression(codegen, p_left_operand, p_stack_level, false, p_initializer, p_index_addr);
- if (src_address_a < 0) {
- return false;
- }
- if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- p_stack_level++; //uses stack for return, increase stack
- }
-
- int src_address_b = _parse_expression(codegen, p_right_operand, p_stack_level, false, p_initializer);
- if (src_address_b < 0) {
- return false;
- }
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
- codegen.opcodes.push_back(op); //which operator
- codegen.opcodes.push_back(src_address_a); // argument 1
- codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
- return true;
-}
-
-bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::BinaryOpNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
- return _create_binary_operator(codegen, on->left_operand, on->right_operand, op, p_stack_level, p_initializer, p_index_addr);
-}
-
-GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::DataType &p_datatype) const {
+GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::DataType &p_datatype, GDScript *p_owner) const {
if (!p_datatype.is_set() || !p_datatype.is_hard_type()) {
return GDScriptDataType();
}
@@ -136,7 +98,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
} break;
case GDScriptParser::DataType::SCRIPT: {
result.kind = GDScriptDataType::SCRIPT;
- result.script_type = p_datatype.script_type;
+ result.script_type = Ref<Script>(p_datatype.script_type).ptr();
result.native_type = result.script_type->get_instance_base_type();
} break;
case GDScriptParser::DataType::CLASS: {
@@ -162,11 +124,11 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
names.pop_back();
}
result.kind = GDScriptDataType::GDSCRIPT;
- result.script_type = script;
+ result.script_type = script.ptr();
result.native_type = script->get_instance_base_type();
} else {
result.kind = GDScriptDataType::GDSCRIPT;
- result.script_type = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path);
+ result.script_type = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path).ptr();
result.native_type = p_datatype.native_type;
}
}
@@ -187,202 +149,73 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
}
}
- return result;
-}
-
-int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::AssignmentNode *p_assignment, int p_stack_level, int p_index_addr) {
- Variant::Operator var_op = Variant::OP_MAX;
-
- switch (p_assignment->operation) {
- case GDScriptParser::AssignmentNode::OP_ADDITION:
- var_op = Variant::OP_ADD;
- break;
- case GDScriptParser::AssignmentNode::OP_SUBTRACTION:
- var_op = Variant::OP_SUBTRACT;
- break;
- case GDScriptParser::AssignmentNode::OP_MULTIPLICATION:
- var_op = Variant::OP_MULTIPLY;
- break;
- case GDScriptParser::AssignmentNode::OP_DIVISION:
- var_op = Variant::OP_DIVIDE;
- break;
- case GDScriptParser::AssignmentNode::OP_MODULO:
- var_op = Variant::OP_MODULE;
- break;
- case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_LEFT:
- var_op = Variant::OP_SHIFT_LEFT;
- break;
- case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_RIGHT:
- var_op = Variant::OP_SHIFT_RIGHT;
- break;
- case GDScriptParser::AssignmentNode::OP_BIT_AND:
- var_op = Variant::OP_BIT_AND;
- break;
- case GDScriptParser::AssignmentNode::OP_BIT_OR:
- var_op = Variant::OP_BIT_OR;
- break;
- case GDScriptParser::AssignmentNode::OP_BIT_XOR:
- var_op = Variant::OP_BIT_XOR;
- break;
- case GDScriptParser::AssignmentNode::OP_NONE: {
- //none
- } break;
- default: {
- ERR_FAIL_V(-1);
- }
+ // Only hold strong reference to the script if it's not the owner of the
+ // element qualified with this type, to avoid cyclic references (leaks).
+ if (result.script_type && result.script_type != p_owner) {
+ result.script_type_ref = Ref<Script>(result.script_type);
}
- // bool initializer = p_expression->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN;
-
- if (var_op == Variant::OP_MAX) {
- return _parse_expression(codegen, p_assignment->assigned_value, p_stack_level, false, false);
- }
-
- if (!_create_binary_operator(codegen, p_assignment->assignee, p_assignment->assigned_value, var_op, p_stack_level, false, p_index_addr)) {
- return -1;
- }
-
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
-}
-
-bool GDScriptCompiler::_generate_typed_assign(CodeGen &codegen, int p_src_address, int p_dst_address, const GDScriptDataType &p_datatype, const GDScriptParser::DataType &p_value_type) {
- if (p_datatype.has_type && p_value_type.is_variant()) {
- // Typed assignment
- switch (p_datatype.kind) {
- case GDScriptDataType::BUILTIN: {
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
- codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2
- } break;
- case GDScriptDataType::NATIVE: {
- int class_idx;
- if (GDScriptLanguage::get_singleton()->get_global_map().has(p_datatype.native_type)) {
- class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_datatype.native_type];
- class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
- } else {
- // _set_error("Invalid native class type '" + String(p_datatype.native_type) + "'.", on->arguments[0]);
- return false;
- }
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE); // perform operator
- codegen.opcodes.push_back(class_idx); // variable type
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2
- } break;
- case GDScriptDataType::SCRIPT:
- case GDScriptDataType::GDSCRIPT: {
- Variant script = p_datatype.script_type;
- int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT); // perform operator
- codegen.opcodes.push_back(idx); // variable type
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2
- } break;
- default: {
- ERR_PRINT("Compiler bug: unresolved assign.");
-
- // Shouldn't get here, but fail-safe to a regular assignment
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
- }
- }
- } else {
- if (p_datatype.kind == GDScriptDataType::BUILTIN && p_value_type.kind == GDScriptParser::DataType::BUILTIN && p_datatype.builtin_type != p_value_type.builtin_type) {
- // Need conversion.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
- codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2
- } else {
- // Either untyped assignment or already type-checked by the parser
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
- codegen.opcodes.push_back(p_dst_address); // argument 1
- codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
- }
- }
- return true;
+ return result;
}
-int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) {
+GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::ExpressionNode *p_expression, bool p_root, bool p_initializer, const GDScriptCodeGenerator::Address &p_index_addr) {
if (p_expression->is_constant) {
- return codegen.get_constant_pos(p_expression->reduced_value);
+ return codegen.add_constant(p_expression->reduced_value);
}
+ GDScriptCodeGenerator *gen = codegen.generator;
+
switch (p_expression->type) {
- //should parse variable declaration and adjust stack accordingly...
case GDScriptParser::Node::IDENTIFIER: {
- //return identifier
- //wait, identifier could be a local variable or something else... careful here, must reference properly
- //as stack may be more interesting to work with
-
- //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases performance a lot.
-
+ // Look for identifiers in current scope.
const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression);
StringName identifier = in->name;
- // TRY STACK!
- if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
- int pos = codegen.stack_identifiers[identifier];
- return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
+ // Try function parameters.
+ if (codegen.parameters.has(identifier)) {
+ return codegen.parameters[identifier];
}
- // TRY LOCAL CONSTANTS!
- if (codegen.local_named_constants.has(identifier)) {
- return codegen.local_named_constants[identifier] | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
+ // Try local variables and constants.
+ if (!p_initializer && codegen.locals.has(identifier)) {
+ return codegen.locals[identifier];
}
- // TRY CLASS MEMBER
+ // Try class members.
if (_is_class_member_property(codegen, identifier)) {
- //get property
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_MEMBER); // perform operator
- codegen.opcodes.push_back(codegen.get_name_map_pos(identifier)); // argument 2 (unary only takes one parameter)
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
+ // Get property.
+ GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Could get the type of the class member here.
+ gen->write_get_member(temp, identifier);
+ return temp;
}
- //TRY MEMBERS!
+ // Try members.
if (!codegen.function_node || !codegen.function_node->is_static) {
- // TRY MEMBER VARIABLES!
- //static function
+ // Try member variables.
if (codegen.script->member_indices.has(identifier)) {
if (codegen.script->member_indices[identifier].getter != StringName() && codegen.script->member_indices[identifier].getter != codegen.function_name) {
// Perform getter.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_RETURN);
- codegen.opcodes.push_back(0); // Argument count.
- codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Base (self).
- codegen.opcodes.push_back(codegen.get_name_map_pos(codegen.script->member_indices[identifier].getter)); // Method name.
- // Destination.
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
+ GDScriptCodeGenerator::Address temp = codegen.add_temporary();
+ Vector<GDScriptCodeGenerator::Address> args; // No argument needed.
+ gen->write_call_self(temp, codegen.script->member_indices[identifier].getter, args);
+ return temp;
} else {
- // No getter or inside getter: direct member access.
+ // No getter or inside getter: direct member access.,
int idx = codegen.script->member_indices[identifier].index;
- return idx | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); //argument (stack root)
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::MEMBER, idx, codegen.script->get_member_type(identifier));
}
}
}
- //TRY CLASS CONSTANTS
-
+ // Try class constants.
GDScript *owner = codegen.script;
while (owner) {
GDScript *scr = owner;
GDScriptNativeClass *nc = nullptr;
while (scr) {
if (scr->constants.has(identifier)) {
- //int idx=scr->constants[identifier];
- int idx = codegen.get_name_map_pos(identifier);
- return idx | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root)
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here.
}
if (scr->native.is_valid()) {
nc = scr->native.ptr();
@@ -390,52 +223,37 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
scr = scr->_base;
}
- // CLASS C++ Integer Constant
-
+ // Class C++ integer constant.
if (nc) {
bool success = false;
int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success);
if (success) {
- Variant key = constant;
- int idx;
-
- if (!codegen.constant_map.has(key)) {
- idx = codegen.constant_map.size();
- codegen.constant_map[key] = idx;
-
- } else {
- idx = codegen.constant_map[key];
- }
-
- return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //make it a local constant (faster access)
+ return codegen.add_constant(constant);
}
}
owner = owner->_owner;
}
- // TRY SIGNALS AND METHODS (can be made callables)
+ // Try signals and methods (can be made callables);
if (codegen.class_node->members_indices.has(identifier)) {
const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]];
if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
// Get like it was a property.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_NAMED); // perform operator
- codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Self.
- codegen.opcodes.push_back(codegen.get_name_map_pos(identifier)); // argument 2 (unary only takes one parameter)
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
+ GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here.
+ GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF);
+
+ gen->write_get_named(temp, identifier, self);
+ return temp;
}
}
if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];
- return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::GLOBAL, idx); // TODO: Get type.
}
- /* TRY GLOBAL CLASSES */
-
+ // Try global classes.
if (ScriptServer::is_global_class(identifier)) {
const GDScriptParser::ClassNode *class_node = codegen.class_node;
while (class_node->outer) {
@@ -450,356 +268,209 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
res = ResourceLoader::load(ScriptServer::get_global_class_path(identifier));
if (res.is_null()) {
_set_error("Can't load global class " + String(identifier) + ", cyclic reference?", p_expression);
- return -1;
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
}
- Variant key = res;
- int idx;
-
- if (!codegen.constant_map.has(key)) {
- idx = codegen.constant_map.size();
- codegen.constant_map[key] = idx;
-
- } else {
- idx = codegen.constant_map[key];
- }
-
- return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //make it a local constant (faster access)
+ return codegen.add_constant(res);
}
#ifdef TOOLS_ENABLED
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
- int idx = codegen.named_globals.find(identifier);
- if (idx == -1) {
- idx = codegen.named_globals.size();
- codegen.named_globals.push_back(identifier);
- }
- return idx | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NAMED_GLOBAL, gen->add_or_get_name(identifier)); // TODO: Get type.
}
#endif
- //not found, error
-
+ // Not found, error.
_set_error("Identifier not found: " + String(identifier), p_expression);
-
- return -1;
-
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
} break;
case GDScriptParser::Node::LITERAL: {
- //return constant
+ // Return constant.
const GDScriptParser::LiteralNode *cn = static_cast<const GDScriptParser::LiteralNode *>(p_expression);
- int idx;
-
- if (!codegen.constant_map.has(cn->value)) {
- idx = codegen.constant_map.size();
- codegen.constant_map[cn->value] = idx;
-
- } else {
- idx = codegen.constant_map[cn->value];
- }
-
- return idx | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root)
-
+ return codegen.add_constant(cn->value);
} break;
case GDScriptParser::Node::SELF: {
//return constant
if (codegen.function_node && codegen.function_node->is_static) {
_set_error("'self' not present in static function!", p_expression);
- return -1;
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
- return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF);
} break;
case GDScriptParser::Node::ARRAY: {
const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression);
- Vector<int> values;
+ Vector<GDScriptCodeGenerator::Address> values;
- int slevel = p_stack_level;
+ // Create the result temporary first since it's the last to be killed.
+ GDScriptDataType array_type;
+ array_type.has_type = true;
+ array_type.kind = GDScriptDataType::BUILTIN;
+ array_type.builtin_type = Variant::ARRAY;
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(array_type);
for (int i = 0; i < an->elements.size(); i++) {
- int ret = _parse_expression(codegen, an->elements[i], slevel);
- if (ret < 0) {
- return ret;
+ GDScriptCodeGenerator::Address val = _parse_expression(codegen, r_error, an->elements[i]);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
-
- values.push_back(ret);
+ values.push_back(val);
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY);
- codegen.opcodes.push_back(values.size());
+ gen->write_construct_array(result, values);
+
for (int i = 0; i < values.size(); i++) {
- codegen.opcodes.push_back(values[i]);
+ if (values[i].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
}
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
-
+ return result;
} break;
case GDScriptParser::Node::DICTIONARY: {
const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression);
- Vector<int> elements;
+ Vector<GDScriptCodeGenerator::Address> elements;
- int slevel = p_stack_level;
+ // Create the result temporary first since it's the last to be killed.
+ GDScriptDataType dict_type;
+ dict_type.has_type = true;
+ dict_type.kind = GDScriptDataType::BUILTIN;
+ dict_type.builtin_type = Variant::DICTIONARY;
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(dict_type);
for (int i = 0; i < dn->elements.size(); i++) {
// Key.
- int ret = -1;
+ GDScriptCodeGenerator::Address element;
switch (dn->style) {
case GDScriptParser::DictionaryNode::PYTHON_DICT:
// Python-style: key is any expression.
- ret = _parse_expression(codegen, dn->elements[i].key, slevel);
- if (ret < 0) {
- return ret;
- }
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
+ element = _parse_expression(codegen, r_error, dn->elements[i].key);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
break;
case GDScriptParser::DictionaryNode::LUA_TABLE:
// Lua-style: key is an identifier interpreted as string.
String key = static_cast<const GDScriptParser::IdentifierNode *>(dn->elements[i].key)->name;
- ret = codegen.get_constant_pos(key);
+ element = codegen.add_constant(key);
break;
}
- elements.push_back(ret);
+ elements.push_back(element);
- ret = _parse_expression(codegen, dn->elements[i].value, slevel);
- if (ret < 0) {
- return ret;
- }
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
+ element = _parse_expression(codegen, r_error, dn->elements[i].value);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- elements.push_back(ret);
+ elements.push_back(element);
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY);
- codegen.opcodes.push_back(dn->elements.size());
+ gen->write_construct_dictionary(result, elements);
+
for (int i = 0; i < elements.size(); i++) {
- codegen.opcodes.push_back(elements[i]);
+ if (elements[i].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
}
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
-
+ return result;
} break;
case GDScriptParser::Node::CAST: {
const GDScriptParser::CastNode *cn = static_cast<const GDScriptParser::CastNode *>(p_expression);
+ GDScriptDataType cast_type = _gdtype_from_datatype(cn->cast_type->get_datatype());
- int slevel = p_stack_level;
- int src_addr = _parse_expression(codegen, cn->operand, slevel);
- if (src_addr < 0) {
- return src_addr;
- }
- if (src_addr & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
+ // Create temporary for result first since it will be deleted last.
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(cast_type);
- GDScriptDataType cast_type = _gdtype_from_datatype(cn->cast_type->get_datatype());
+ GDScriptCodeGenerator::Address source = _parse_expression(codegen, r_error, cn->operand);
- switch (cast_type.kind) {
- case GDScriptDataType::BUILTIN: {
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_BUILTIN);
- codegen.opcodes.push_back(cast_type.builtin_type);
- } break;
- case GDScriptDataType::NATIVE: {
- int class_idx;
- if (GDScriptLanguage::get_singleton()->get_global_map().has(cast_type.native_type)) {
- class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cast_type.native_type];
- class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
- } else {
- _set_error("Invalid native class type '" + String(cast_type.native_type) + "'.", cn);
- return -1;
- }
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_NATIVE); // perform operator
- codegen.opcodes.push_back(class_idx); // variable type
- } break;
- case GDScriptDataType::SCRIPT:
- case GDScriptDataType::GDSCRIPT: {
- Variant script = cast_type.script_type;
- int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
+ gen->write_cast(result, source, cast_type);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_SCRIPT); // perform operator
- codegen.opcodes.push_back(idx); // variable type
- } break;
- default: {
- _set_error("Parser bug: unresolved data type.", cn);
- return -1;
- }
+ if (source.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- codegen.opcodes.push_back(src_addr); // source address
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
- codegen.alloc_stack(p_stack_level);
- return dst_addr;
-
+ return source;
} break;
- //hell breaks loose
-
-#define OPERATOR_RETURN \
- int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); \
- codegen.opcodes.push_back(dst_addr); \
- codegen.alloc_stack(p_stack_level); \
- return dst_addr
-
case GDScriptParser::Node::CALL: {
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
- if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name) != Variant::VARIANT_MAX) {
- //construct a basic type
-
- Variant::Type vtype = GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
+ GDScriptDataType type = _gdtype_from_datatype(call->get_datatype());
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(type);
- Vector<int> arguments;
- int slevel = p_stack_level;
- for (int i = 0; i < call->arguments.size(); i++) {
- int ret = _parse_expression(codegen, call->arguments[i], slevel);
- if (ret < 0) {
- return ret;
- }
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
- arguments.push_back(ret);
+ Vector<GDScriptCodeGenerator::Address> arguments;
+ for (int i = 0; i < call->arguments.size(); i++) {
+ GDScriptCodeGenerator::Address arg = _parse_expression(codegen, r_error, call->arguments[i]);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
+ arguments.push_back(arg);
+ }
- //push call bytecode
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT); // basic type constructor
- codegen.opcodes.push_back(vtype); //instance
- codegen.opcodes.push_back(arguments.size()); //argument count
- codegen.alloc_call(arguments.size());
- for (int i = 0; i < arguments.size(); i++) {
- codegen.opcodes.push_back(arguments[i]); //arguments
- }
+ if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name) != Variant::VARIANT_MAX) {
+ // Construct a built-in type.
+ Variant::Type vtype = GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
+ gen->write_construct(result, vtype, arguments);
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_function(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name) != GDScriptFunctions::FUNC_MAX) {
- //built in function
-
- Vector<int> arguments;
- int slevel = p_stack_level;
- for (int i = 0; i < call->arguments.size(); i++) {
- int ret = _parse_expression(codegen, call->arguments[i], slevel);
- if (ret < 0) {
- return ret;
- }
-
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
-
- arguments.push_back(ret);
- }
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptParser::get_builtin_function(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name));
- codegen.opcodes.push_back(arguments.size());
- codegen.alloc_call(arguments.size());
- for (int i = 0; i < arguments.size(); i++) {
- codegen.opcodes.push_back(arguments[i]);
- }
-
+ // Built-in function.
+ GDScriptFunctions::Function func = GDScriptParser::get_builtin_function(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
+ gen->write_call_builtin(result, func, arguments);
} else {
- //regular function
-
+ // Regular function.
const GDScriptParser::ExpressionNode *callee = call->callee;
- Vector<int> arguments;
- int slevel = p_stack_level;
-
- // TODO: Use callables when possible if needed.
- int ret = -1;
- int super_address = -1;
if (call->is_super) {
// Super call.
- if (call->callee == nullptr) {
- // Implicit super function call.
- super_address = codegen.get_name_map_pos(codegen.function_node->identifier->name);
- } else {
- super_address = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
- }
+ gen->write_super_call(result, call->function_name, arguments);
} else {
if (callee->type == GDScriptParser::Node::IDENTIFIER) {
// Self function call.
if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") {
- ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS);
+ GDScriptCodeGenerator::Address self;
+ self.mode = GDScriptCodeGenerator::Address::CLASS;
+ gen->write_call(result, self, call->function_name, arguments);
} else {
- ret = (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ gen->write_call_self(result, call->function_name, arguments);
}
- arguments.push_back(ret);
- ret = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
- arguments.push_back(ret);
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee);
if (subscript->is_attribute) {
- ret = _parse_expression(codegen, subscript->base, slevel);
- if (ret < 0) {
- return ret;
+ GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
+ if (within_await) {
+ gen->write_call_async(result, base, call->function_name, arguments);
+ } else {
+ gen->write_call(result, base, call->function_name, arguments);
+ }
+ if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- arguments.push_back(ret);
- arguments.push_back(codegen.get_name_map_pos(subscript->attribute->name));
} else {
_set_error("Cannot call something that isn't a function.", call->callee);
- return -1;
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
} else {
- _set_error("Cannot call something that isn't a function.", call->callee);
- return -1;
- }
- }
-
- for (int i = 0; i < call->arguments.size(); i++) {
- ret = _parse_expression(codegen, call->arguments[i], slevel);
- if (ret < 0) {
- return ret;
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
- if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
- arguments.push_back(ret);
- }
-
- int opcode = GDScriptFunction::OPCODE_CALL_RETURN;
- if (call->is_super) {
- opcode = GDScriptFunction::OPCODE_CALL_SELF_BASE;
- } else if (within_await) {
- opcode = GDScriptFunction::OPCODE_CALL_ASYNC;
- } else if (p_root) {
- opcode = GDScriptFunction::OPCODE_CALL;
}
+ }
- codegen.opcodes.push_back(opcode); // perform operator
- if (call->is_super) {
- codegen.opcodes.push_back(super_address);
- }
- codegen.opcodes.push_back(call->arguments.size());
- codegen.alloc_call(call->arguments.size());
- for (int i = 0; i < arguments.size(); i++) {
- codegen.opcodes.push_back(arguments[i]);
+ for (int i = 0; i < arguments.size(); i++) {
+ if (arguments[i].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
}
- OPERATOR_RETURN;
+ return result;
} break;
case GDScriptParser::Node::GET_NODE: {
const GDScriptParser::GetNodeNode *get_node = static_cast<const GDScriptParser::GetNodeNode *>(p_expression);
@@ -816,59 +487,55 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
}
- int arg_address = codegen.get_constant_pos(NodePath(node_name));
+ Vector<GDScriptCodeGenerator::Address> args;
+ args.push_back(codegen.add_constant(NodePath(node_name)));
- codegen.opcodes.push_back(p_root ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN);
- codegen.opcodes.push_back(1); // number of arguments.
- codegen.alloc_call(1);
- codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // self.
- codegen.opcodes.push_back(codegen.get_name_map_pos("get_node")); // function.
- codegen.opcodes.push_back(arg_address); // argument (NodePath).
- OPERATOR_RETURN;
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(get_node->get_datatype()));
+
+ MethodBind *get_node_method = ClassDB::get_method("Node", "get_node");
+ gen->write_call_method_bind(result, GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), get_node_method, args);
+
+ return result;
} break;
case GDScriptParser::Node::PRELOAD: {
const GDScriptParser::PreloadNode *preload = static_cast<const GDScriptParser::PreloadNode *>(p_expression);
// Add resource as constant.
- return codegen.get_constant_pos(preload->resource);
+ return codegen.add_constant(preload->resource);
} break;
case GDScriptParser::Node::AWAIT: {
const GDScriptParser::AwaitNode *await = static_cast<const GDScriptParser::AwaitNode *>(p_expression);
- int slevel = p_stack_level;
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(p_expression->get_datatype()));
within_await = true;
- int argument = _parse_expression(codegen, await->to_await, slevel);
+ GDScriptCodeGenerator::Address argument = _parse_expression(codegen, r_error, await->to_await);
within_await = false;
- if (argument < 0) {
- return argument;
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- if ((argument >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
+
+ gen->write_await(result, argument);
+
+ if (argument.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- //push call bytecode
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_AWAIT);
- codegen.opcodes.push_back(argument);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_AWAIT_RESUME);
- //next will be where to place the result :)
- OPERATOR_RETURN;
+ return result;
} break;
-
- //indexing operator
+ // Indexing operator.
case GDScriptParser::Node::SUBSCRIPT: {
- int slevel = p_stack_level;
-
const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(p_expression);
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(subscript->get_datatype()));
- int from = _parse_expression(codegen, subscript->base, slevel);
- if (from < 0) {
- return from;
+ GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
bool named = subscript->is_attribute;
- int index;
- if (p_index_addr != 0) {
+ StringName name;
+ GDScriptCodeGenerator::Address index;
+ if (p_index_addr.mode != GDScriptCodeGenerator::Address::NIL) {
index = p_index_addr;
} else if (subscript->is_attribute) {
if (subscript->base->type == GDScriptParser::Node::SELF && codegen.script) {
@@ -879,306 +546,179 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
if (MI && MI->get().getter == codegen.function_name) {
String n = identifier->name;
_set_error("Must use '" + n + "' instead of 'self." + n + "' in getter.", identifier);
- return -1;
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
#endif
if (MI && MI->get().getter == "") {
- // Faster than indexing self (as if no self. had been used)
- return (MI->get().index) | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS);
+ // Remove result temp as we don't need it.
+ gen->pop_temporary();
+ // Faster than indexing self (as if no self. had been used).
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::MEMBER, MI->get().index, _gdtype_from_datatype(subscript->get_datatype()));
}
}
- index = codegen.get_name_map_pos(subscript->attribute->name);
-
+ name = subscript->attribute->name;
+ named = true;
} else {
if (subscript->index->type == GDScriptParser::Node::LITERAL && static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value.get_type() == Variant::STRING) {
- //also, somehow, named (speed up anyway)
- StringName name = static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value;
- index = codegen.get_name_map_pos(name);
+ // Also, somehow, named (speed up anyway).
+ name = static_cast<const GDScriptParser::LiteralNode *>(subscript->index)->value;
named = true;
-
} else {
- //regular indexing
- if (from & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
-
- index = _parse_expression(codegen, subscript->index, slevel);
- if (index < 0) {
- return index;
+ // Regular indexing.
+ index = _parse_expression(codegen, r_error, subscript->index);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
}
}
- codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET); // perform operator
- codegen.opcodes.push_back(from); // argument 1
- codegen.opcodes.push_back(index); // argument 2 (unary only takes one parameter)
- OPERATOR_RETURN;
+ if (named) {
+ gen->write_get_named(result, name, base);
+ } else {
+ gen->write_get(result, index, base);
+ }
+
+ if (index.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+
+ return result;
} break;
case GDScriptParser::Node::UNARY_OPERATOR: {
- //unary operators
const GDScriptParser::UnaryOpNode *unary = static_cast<const GDScriptParser::UnaryOpNode *>(p_expression);
- switch (unary->operation) {
- case GDScriptParser::UnaryOpNode::OP_NEGATIVE: {
- if (!_create_unary_operator(codegen, unary, Variant::OP_NEGATE, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::UnaryOpNode::OP_POSITIVE: {
- if (!_create_unary_operator(codegen, unary, Variant::OP_POSITIVE, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::UnaryOpNode::OP_LOGIC_NOT: {
- if (!_create_unary_operator(codegen, unary, Variant::OP_NOT, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::UnaryOpNode::OP_COMPLEMENT: {
- if (!_create_unary_operator(codegen, unary, Variant::OP_BIT_NEGATE, p_stack_level)) {
- return -1;
- }
- } break;
+
+ GDScriptCodeGenerator::Address result = codegen.add_temporary();
+
+ GDScriptCodeGenerator::Address operand = _parse_expression(codegen, r_error, unary->operand);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+
+ gen->write_operator(result, unary->variant_op, operand, GDScriptCodeGenerator::Address());
+
+ if (operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- OPERATOR_RETURN;
+
+ return result;
}
case GDScriptParser::Node::BINARY_OPERATOR: {
- //binary operators (in precedence order)
const GDScriptParser::BinaryOpNode *binary = static_cast<const GDScriptParser::BinaryOpNode *>(p_expression);
+ GDScriptCodeGenerator::Address result = codegen.add_temporary();
+
switch (binary->operation) {
case GDScriptParser::BinaryOpNode::OP_LOGIC_AND: {
- // AND operator with early out on failure
+ // AND operator with early out on failure.
+ GDScriptCodeGenerator::Address left_operand = _parse_expression(codegen, r_error, binary->left_operand);
+ gen->write_and_left_operand(left_operand);
+ GDScriptCodeGenerator::Address right_operand = _parse_expression(codegen, r_error, binary->right_operand);
+ gen->write_and_right_operand(right_operand);
- int res = _parse_expression(codegen, binary->left_operand, p_stack_level);
- if (res < 0) {
- return res;
+ gen->write_end_and(result);
+
+ if (right_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(res);
- int jump_fail_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
-
- res = _parse_expression(codegen, binary->right_operand, p_stack_level);
- if (res < 0) {
- return res;
+ if (left_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(res);
- int jump_fail_pos2 = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
-
- codegen.alloc_stack(p_stack_level); //it will be used..
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(codegen.opcodes.size() + 3);
- codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size();
- codegen.opcodes.write[jump_fail_pos2] = codegen.opcodes.size();
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
-
} break;
case GDScriptParser::BinaryOpNode::OP_LOGIC_OR: {
- // OR operator with early out on success
+ // OR operator with early out on success.
+ GDScriptCodeGenerator::Address left_operand = _parse_expression(codegen, r_error, binary->left_operand);
+ gen->write_or_left_operand(left_operand);
+ GDScriptCodeGenerator::Address right_operand = _parse_expression(codegen, r_error, binary->right_operand);
+ gen->write_or_right_operand(right_operand);
+
+ gen->write_end_or(result);
- int res = _parse_expression(codegen, binary->left_operand, p_stack_level);
- if (res < 0) {
- return res;
+ if (right_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
- codegen.opcodes.push_back(res);
- int jump_success_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
-
- res = _parse_expression(codegen, binary->right_operand, p_stack_level);
- if (res < 0) {
- return res;
+ if (left_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
- codegen.opcodes.push_back(res);
- int jump_success_pos2 = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
-
- codegen.alloc_stack(p_stack_level); //it will be used..
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(codegen.opcodes.size() + 3);
- codegen.opcodes.write[jump_success_pos] = codegen.opcodes.size();
- codegen.opcodes.write[jump_success_pos2] = codegen.opcodes.size();
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
-
} break;
case GDScriptParser::BinaryOpNode::OP_TYPE_TEST: {
- int slevel = p_stack_level;
+ GDScriptCodeGenerator::Address operand = _parse_expression(codegen, r_error, binary->left_operand);
- int src_address_a = _parse_expression(codegen, binary->left_operand, slevel);
- if (src_address_a < 0) {
- return -1;
- }
-
- if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++; //uses stack for return, increase stack
- }
-
- int src_address_b = -1;
- bool builtin = false;
if (binary->right_operand->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<const GDScriptParser::IdentifierNode *>(binary->right_operand)->name) != Variant::VARIANT_MAX) {
- // `is` with builtin type
- builtin = true;
- src_address_b = (int)GDScriptParser::get_builtin_type(static_cast<const GDScriptParser::IdentifierNode *>(binary->right_operand)->name);
+ // `is` with builtin type)
+ Variant::Type type = GDScriptParser::get_builtin_type(static_cast<const GDScriptParser::IdentifierNode *>(binary->right_operand)->name);
+ gen->write_type_test_builtin(result, operand, type);
} else {
- src_address_b = _parse_expression(codegen, binary->right_operand, slevel);
- if (src_address_b < 0) {
- return -1;
+ GDScriptCodeGenerator::Address type = _parse_expression(codegen, r_error, binary->right_operand);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+ gen->write_type_test(result, operand, type);
+ if (type.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
}
+ } break;
+ default: {
+ GDScriptCodeGenerator::Address left_operand = _parse_expression(codegen, r_error, binary->left_operand);
+ GDScriptCodeGenerator::Address right_operand = _parse_expression(codegen, r_error, binary->right_operand);
- codegen.opcodes.push_back(builtin ? GDScriptFunction::OPCODE_IS_BUILTIN : GDScriptFunction::OPCODE_EXTENDS_TEST); // perform operator
- codegen.opcodes.push_back(src_address_a); // argument 1
- codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
+ gen->write_operator(result, binary->variant_op, left_operand, right_operand);
- } break;
- case GDScriptParser::BinaryOpNode::OP_CONTENT_TEST: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_IN, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_EQUAL: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_EQUAL, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_NOT_EQUAL: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_NOT_EQUAL, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_LESS: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_LESS, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_LESS_EQUAL: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_LESS_EQUAL, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_GREATER: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_GREATER, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_COMP_GREATER_EQUAL: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_GREATER_EQUAL, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_ADDITION: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_ADD, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_SUBTRACTION: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_SUBTRACT, p_stack_level)) {
- return -1;
+ if (right_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- } break;
- case GDScriptParser::BinaryOpNode::OP_MULTIPLICATION: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_MULTIPLY, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_DIVISION: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_DIVIDE, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_MODULO: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_MODULE, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_BIT_AND: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_AND, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_BIT_OR: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_OR, p_stack_level)) {
- return -1;
+ if (left_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- } break;
- case GDScriptParser::BinaryOpNode::OP_BIT_XOR: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_BIT_XOR, p_stack_level)) {
- return -1;
- }
- } break;
- //shift
- case GDScriptParser::BinaryOpNode::OP_BIT_LEFT_SHIFT: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_SHIFT_LEFT, p_stack_level)) {
- return -1;
- }
- } break;
- case GDScriptParser::BinaryOpNode::OP_BIT_RIGHT_SHIFT: {
- if (!_create_binary_operator(codegen, binary, Variant::OP_SHIFT_RIGHT, p_stack_level)) {
- return -1;
- }
- } break;
+ }
}
- OPERATOR_RETURN;
+ return result;
} break;
- // ternary operators
case GDScriptParser::Node::TERNARY_OPERATOR: {
- // x IF a ELSE y operator with early out on failure
-
+ // x IF a ELSE y operator with early out on failure.
const GDScriptParser::TernaryOpNode *ternary = static_cast<const GDScriptParser::TernaryOpNode *>(p_expression);
- int res = _parse_expression(codegen, ternary->condition, p_stack_level);
- if (res < 0) {
- return res;
- }
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(res);
- int jump_fail_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
+ GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(ternary->get_datatype()));
- res = _parse_expression(codegen, ternary->true_expr, p_stack_level);
- if (res < 0) {
- return res;
- }
+ gen->write_start_ternary(result);
- codegen.alloc_stack(p_stack_level); //it will be used..
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(res);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- int jump_past_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
+ GDScriptCodeGenerator::Address condition = _parse_expression(codegen, r_error, ternary->condition);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+ gen->write_ternary_condition(condition);
- codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size();
- res = _parse_expression(codegen, ternary->false_expr, p_stack_level);
- if (res < 0) {
- return res;
+ if (condition.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
- codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.opcodes.push_back(res);
+ GDScriptCodeGenerator::Address true_expr = _parse_expression(codegen, r_error, ternary->true_expr);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+ gen->write_ternary_true_expr(true_expr);
+ if (true_expr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
- codegen.opcodes.write[jump_past_pos] = codegen.opcodes.size();
+ GDScriptCodeGenerator::Address false_expr = _parse_expression(codegen, r_error, ternary->false_expr);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+ gen->write_ternary_false_expr(false_expr);
+ if (false_expr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
- return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
+ gen->write_end_ternary();
+ return result;
} break;
- //assignment operators
case GDScriptParser::Node::ASSIGNMENT: {
const GDScriptParser::AssignmentNode *assignment = static_cast<const GDScriptParser::AssignmentNode *>(p_expression);
@@ -1186,20 +726,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
// SET (chained) MODE!
const GDScriptParser::SubscriptNode *subscript = static_cast<GDScriptParser::SubscriptNode *>(assignment->assignee);
#ifdef DEBUG_ENABLED
- if (subscript->is_attribute) {
- if (subscript->base->type == GDScriptParser::Node::SELF && codegen.script) {
- const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(subscript->attribute->name);
- if (MI && MI->get().setter == codegen.function_name) {
- String n = subscript->attribute->name;
- _set_error("Must use '" + n + "' instead of 'self." + n + "' in setter.", subscript);
- return -1;
- }
+ if (subscript->is_attribute && subscript->base->type == GDScriptParser::Node::SELF && codegen.script) {
+ const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(subscript->attribute->name);
+ if (MI && MI->get().setter == codegen.function_name) {
+ String n = subscript->attribute->name;
+ _set_error("Must use '" + n + "' instead of 'self." + n + "' in setter.", subscript);
+ r_error = ERR_COMPILATION_FAILED;
+ return GDScriptCodeGenerator::Address();
}
}
#endif
-
- int slevel = p_stack_level;
-
/* Find chain of sets */
StringName assign_property;
@@ -1207,13 +743,12 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
List<const GDScriptParser::SubscriptNode *> chain;
{
- //create get/set chain
+ // Create get/set chain.
const GDScriptParser::SubscriptNode *n = subscript;
while (true) {
chain.push_back(n);
-
if (n->base->type != GDScriptParser::Node::SUBSCRIPT) {
- //check for a built-in property
+ // Check for a built-in property.
if (n->base->type == GDScriptParser::Node::IDENTIFIER) {
GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->base);
if (_is_class_member_property(codegen, identifier->name)) {
@@ -1228,366 +763,396 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
/* Chain of gets */
- //get at (potential) root stack pos, so it can be returned
- int prev_pos = _parse_expression(codegen, chain.back()->get()->base, slevel);
- if (prev_pos < 0) {
- return prev_pos;
+ // Get at (potential) root stack pos, so it can be returned.
+ GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, chain.back()->get()->base);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- int retval = prev_pos;
- if (retval & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
+ GDScriptCodeGenerator::Address prev_base = base;
- Vector<int> setchain;
+ struct ChainInfo {
+ bool is_named = false;
+ GDScriptCodeGenerator::Address base;
+ GDScriptCodeGenerator::Address key;
+ StringName name;
+ };
- if (assign_property != StringName()) {
- // recover and assign at the end, this allows stuff like
- // position.x+=2.0
- // in Node2D
- setchain.push_back(prev_pos);
- setchain.push_back(codegen.get_name_map_pos(assign_property));
- setchain.push_back(GDScriptFunction::OPCODE_SET_MEMBER);
- }
+ List<ChainInfo> set_chain;
for (List<const GDScriptParser::SubscriptNode *>::Element *E = chain.back(); E; E = E->prev()) {
- if (E == chain.front()) { //ignore first
+ if (E == chain.front()) {
+ // Skip the main subscript, since we'll assign to that.
break;
}
-
const GDScriptParser::SubscriptNode *subscript_elem = E->get();
- int key_idx;
+ GDScriptCodeGenerator::Address value = codegen.add_temporary(_gdtype_from_datatype(subscript_elem->get_datatype()));
+ GDScriptCodeGenerator::Address key;
+ StringName name;
if (subscript_elem->is_attribute) {
- key_idx = codegen.get_name_map_pos(subscript_elem->attribute->name);
- //printf("named key %x\n",key_idx);
-
+ name = subscript_elem->attribute->name;
+ gen->write_get_named(value, name, prev_base);
} else {
- if (prev_pos & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) {
- slevel++;
- codegen.alloc_stack(slevel);
+ key = _parse_expression(codegen, r_error, subscript_elem->index);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
-
- GDScriptParser::ExpressionNode *key = subscript_elem->index;
- key_idx = _parse_expression(codegen, key, slevel);
- //printf("expr key %x\n",key_idx);
-
- //stack was raised here if retval was stack but..
+ gen->write_get(value, key, prev_base);
}
- if (key_idx < 0) { //error
- return key_idx;
- }
-
- codegen.opcodes.push_back(subscript_elem->is_attribute ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET);
- codegen.opcodes.push_back(prev_pos);
- codegen.opcodes.push_back(key_idx);
- slevel++;
- codegen.alloc_stack(slevel);
- int dst_pos = (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | slevel;
-
- codegen.opcodes.push_back(dst_pos);
-
- //add in reverse order, since it will be reverted
-
- setchain.push_back(dst_pos);
- setchain.push_back(key_idx);
- setchain.push_back(prev_pos);
- setchain.push_back(subscript_elem->is_attribute ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET);
-
- prev_pos = dst_pos;
+ // Store base and key for setting it back later.
+ set_chain.push_front({ subscript_elem->is_attribute, prev_base, key, name }); // Push to front to invert the list.
+ prev_base = value;
}
- setchain.invert();
-
- int set_index;
-
+ // Get value to assign.
+ GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
+ // Get the key if needed.
+ GDScriptCodeGenerator::Address key;
+ StringName name;
if (subscript->is_attribute) {
- set_index = codegen.get_name_map_pos(subscript->attribute->name);
+ name = subscript->attribute->name;
} else {
- set_index = _parse_expression(codegen, subscript->index, slevel + 1);
+ key = _parse_expression(codegen, r_error, subscript->index);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
}
- if (set_index < 0) { //error
- return set_index;
+ // Perform operator if any.
+ if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
+ GDScriptCodeGenerator::Address value = codegen.add_temporary();
+ if (subscript->is_attribute) {
+ gen->write_get_named(value, name, prev_base);
+ } else {
+ gen->write_get(value, key, prev_base);
+ }
+ gen->write_operator(value, assignment->variant_op, value, assigned);
+ if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ assigned = value;
}
- if (set_index & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++;
- codegen.alloc_stack(slevel);
+ // Perform assignment.
+ if (subscript->is_attribute) {
+ gen->write_set_named(prev_base, name, assigned);
+ } else {
+ gen->write_set(prev_base, key, assigned);
}
-
- int set_value = _parse_assign_right_expression(codegen, assignment, slevel + 1, subscript->is_attribute ? 0 : set_index);
- if (set_value < 0) { //error
- return set_value;
+ if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
}
- codegen.opcodes.push_back(subscript->is_attribute ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET);
- codegen.opcodes.push_back(prev_pos);
- codegen.opcodes.push_back(set_index);
- codegen.opcodes.push_back(set_value);
+ assigned = prev_base;
- for (int i = 0; i < setchain.size(); i++) {
- codegen.opcodes.push_back(setchain[i]);
+ // Set back the values into their bases.
+ for (List<ChainInfo>::Element *E = set_chain.front(); E; E = E->next()) {
+ const ChainInfo &info = E->get();
+ if (!info.is_named) {
+ gen->write_set(info.base, info.key, assigned);
+ if (info.key.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ } else {
+ gen->write_set_named(info.base, info.name, assigned);
+ }
+ if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ assigned = info.base;
}
- return retval;
+ // If this is a local member, also assign to it.
+ // This allow things like: position.x += 2.0
+ if (assign_property != StringName()) {
+ gen->write_set_member(assigned, assign_property);
+ }
+ if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
} else if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER && _is_class_member_property(codegen, static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name)) {
- //assignment to member property
-
- int slevel = p_stack_level;
-
- int src_address = _parse_assign_right_expression(codegen, assignment, slevel);
- if (src_address < 0) {
- return -1;
+ // Assignment to member property.
+ GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
+ GDScriptCodeGenerator::Address assign_temp = assigned;
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_SET_MEMBER);
- codegen.opcodes.push_back(codegen.get_name_map_pos(name));
- codegen.opcodes.push_back(src_address);
+ if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
+ GDScriptCodeGenerator::Address member = codegen.add_temporary();
+ gen->write_get_member(member, name);
+ gen->write_operator(assigned, assignment->variant_op, member, assigned);
+ gen->pop_temporary();
+ }
- return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
- } else {
- //REGULAR ASSIGNMENT MODE!!
+ gen->write_set_member(assigned, name);
- int slevel = p_stack_level;
- int dst_address_a = -1;
+ if (assign_temp.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ } else {
+ // Regular assignment.
+ GDScriptCodeGenerator::Address target;
bool has_setter = false;
bool is_in_setter = false;
StringName setter_function;
if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) {
StringName var_name = static_cast<const GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
- if (!codegen.stack_identifiers.has(var_name) && codegen.script->member_indices.has(var_name)) {
+ if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) {
setter_function = codegen.script->member_indices[var_name].setter;
if (setter_function != StringName()) {
has_setter = true;
is_in_setter = setter_function == codegen.function_name;
- dst_address_a = codegen.script->member_indices[var_name].index;
+ target.mode = GDScriptCodeGenerator::Address::MEMBER;
+ target.address = codegen.script->member_indices[var_name].index;
}
}
}
if (has_setter) {
- if (is_in_setter) {
- // Use direct member access.
- dst_address_a |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
- } else {
+ if (!is_in_setter) {
// Store stack slot for the temp value.
- dst_address_a = slevel++;
- codegen.alloc_stack(slevel);
- dst_address_a |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
+ target = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype()));
}
} else {
- dst_address_a = _parse_expression(codegen, assignment->assignee, slevel);
- if (dst_address_a < 0) {
- return -1;
+ target = _parse_expression(codegen, r_error, assignment->assignee);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
+ }
- if (dst_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
- slevel++;
- codegen.alloc_stack(slevel);
- }
+ GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value);
+ GDScriptCodeGenerator::Address op_result;
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- int src_address_b = _parse_assign_right_expression(codegen, assignment, slevel);
- if (src_address_b < 0) {
- return -1;
+ if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
+ // Perform operation.
+ op_result = codegen.add_temporary();
+ gen->write_operator(op_result, assignment->variant_op, target, assigned);
+ } else {
+ op_result = assigned;
+ assigned = GDScriptCodeGenerator::Address();
}
GDScriptDataType assign_type = _gdtype_from_datatype(assignment->assignee->get_datatype());
if (has_setter && !is_in_setter) {
// Call setter.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL);
- codegen.opcodes.push_back(1); // Argument count.
- codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); // Base (self).
- codegen.opcodes.push_back(codegen.get_name_map_pos(setter_function)); // Method name.
- codegen.opcodes.push_back(dst_address_a); // Argument.
- codegen.opcodes.push_back(dst_address_a); // Result address (won't be used here).
- codegen.alloc_call(1);
- } else if (!_generate_typed_assign(codegen, src_address_b, dst_address_a, assign_type, assignment->assigned_value->get_datatype())) {
- return -1;
+ Vector<GDScriptCodeGenerator::Address> args;
+ args.push_back(op_result);
+ gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args);
+ } else {
+ // Just assign.
+ gen->write_assign(target, op_result);
}
- return dst_address_a; //if anything, returns wathever was assigned or correct stack position
+ if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
+ if (target.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
}
+ return GDScriptCodeGenerator::Address(); // Assignment does not return a value.
} break;
-#undef OPERATOR_RETURN
- //TYPE_TYPE,
default: {
- ERR_FAIL_V_MSG(-1, "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); //unreachable code
+ ERR_FAIL_V_MSG(GDScriptCodeGenerator::Address(), "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); // Unreachable code.
} break;
}
}
-Error GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, const GDScriptParser::PatternNode *p_pattern, int p_stack_level, int p_value_addr, int p_type_addr, int &r_bound_variables, Vector<int> &r_patch_addresses, Vector<int> &r_block_patch_address) {
- // TODO: Many "repeated" code here that could be abstracted. This compiler is going away when new VM arrives though, so...
+GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, Error &r_error, const GDScriptParser::PatternNode *p_pattern, const GDScriptCodeGenerator::Address &p_value_addr, const GDScriptCodeGenerator::Address &p_type_addr, const GDScriptCodeGenerator::Address &p_previous_test, bool p_is_first, bool p_is_nested) {
switch (p_pattern->pattern_type) {
case GDScriptParser::PatternNode::PT_LITERAL: {
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
+
// Get literal type into constant map.
- int literal_type_addr = -1;
- if (!codegen.constant_map.has((int)p_pattern->literal->value.get_type())) {
- literal_type_addr = codegen.constant_map.size();
- codegen.constant_map[(int)p_pattern->literal->value.get_type()] = literal_type_addr;
+ GDScriptCodeGenerator::Address literal_type_addr = codegen.add_constant((int)p_pattern->literal->value.get_type());
- } else {
- literal_type_addr = codegen.constant_map[(int)p_pattern->literal->value.get_type()];
- }
- literal_type_addr |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS;
+ // Equality is always a boolean.
+ GDScriptDataType equality_type;
+ equality_type.has_type = true;
+ equality_type.kind = GDScriptDataType::BUILTIN;
+ equality_type.builtin_type = Variant::BOOL;
// Check type equality.
- int equality_addr = p_stack_level++;
- equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(p_stack_level);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_type_addr);
- codegen.opcodes.push_back(literal_type_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if not the same type.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ GDScriptCodeGenerator::Address type_equality_addr = codegen.add_temporary(equality_type);
+ codegen.generator->write_operator(type_equality_addr, Variant::OP_EQUAL, p_type_addr, literal_type_addr);
+ codegen.generator->write_and_left_operand(type_equality_addr);
// Get literal.
- int literal_addr = _parse_expression(codegen, p_pattern->literal, p_stack_level);
+ GDScriptCodeGenerator::Address literal_addr = _parse_expression(codegen, r_error, p_pattern->literal);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
+ }
// Check value equality.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_value_addr);
- codegen.opcodes.push_back(literal_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if doesn't match.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
-
- // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- r_block_patch_address.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ GDScriptCodeGenerator::Address equality_addr = codegen.add_temporary(equality_type);
+ codegen.generator->write_operator(equality_addr, Variant::OP_EQUAL, p_value_addr, literal_addr);
+ codegen.generator->write_and_right_operand(equality_addr);
+
+ // AND both together (reuse temporary location).
+ codegen.generator->write_end_and(type_equality_addr);
+
+ codegen.generator->pop_temporary(); // Remove equality_addr from stack.
+
+ if (literal_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
+
+ // If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
+ if (p_is_nested) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_and_right_operand(type_equality_addr);
+ codegen.generator->write_end_and(p_previous_test);
+ } else if (!p_is_first) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_or_right_operand(type_equality_addr);
+ codegen.generator->write_end_or(p_previous_test);
+ } else {
+ // Just assign this value to the accumulator temporary.
+ codegen.generator->write_assign(p_previous_test, type_equality_addr);
+ }
+ codegen.generator->pop_temporary(); // Remove type_equality_addr.
+
+ return p_previous_test;
} break;
case GDScriptParser::PatternNode::PT_EXPRESSION: {
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
+ // Create the result temps first since it's the last to go away.
+ GDScriptCodeGenerator::Address result_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address equality_test_addr = codegen.add_temporary();
+
// Evaluate expression.
- int expr_addr = _parse_expression(codegen, p_pattern->expression, p_stack_level);
- if ((expr_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- p_stack_level++;
- codegen.alloc_stack(p_stack_level);
+ GDScriptCodeGenerator::Address expr_addr;
+ expr_addr = _parse_expression(codegen, r_error, p_pattern->expression);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
// Evaluate expression type.
- int expr_type_addr = p_stack_level++;
- expr_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(p_stack_level);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(expr_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(expr_type_addr); // Address to result.
+ Vector<GDScriptCodeGenerator::Address> typeof_args;
+ typeof_args.push_back(expr_addr);
+ codegen.generator->write_call_builtin(result_addr, GDScriptFunctions::TYPE_OF, typeof_args);
// Check type equality.
- int equality_addr = p_stack_level++;
- equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(p_stack_level);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_type_addr);
- codegen.opcodes.push_back(expr_type_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if not the same type.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, result_addr);
+ codegen.generator->write_and_left_operand(result_addr);
// Check value equality.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_value_addr);
- codegen.opcodes.push_back(expr_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if doesn't match.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
-
- // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- r_block_patch_address.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
- } break;
- case GDScriptParser::PatternNode::PT_BIND: {
- // Create new stack variable.
- int bind_addr = p_stack_level | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
- codegen.add_stack_identifier(p_pattern->bind->name, p_stack_level++);
- codegen.alloc_stack(p_stack_level);
- r_bound_variables++;
+ codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_value_addr, expr_addr);
+ codegen.generator->write_and_right_operand(equality_test_addr);
- // Assign value to bound variable.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
- codegen.opcodes.push_back(bind_addr); // Destination.
- codegen.opcodes.push_back(p_value_addr); // Source.
- // Not need to block jump because bind happens only once.
+ // AND both type and value equality.
+ codegen.generator->write_end_and(result_addr);
+
+ // We don't need the expression temporary anymore.
+ if (expr_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
+ codegen.generator->pop_temporary(); // Remove type equality temporary.
+
+ // If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
+ if (p_is_nested) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_and_right_operand(result_addr);
+ codegen.generator->write_end_and(p_previous_test);
+ } else if (!p_is_first) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_or_right_operand(result_addr);
+ codegen.generator->write_end_or(p_previous_test);
+ } else {
+ // Just assign this value to the accumulator temporary.
+ codegen.generator->write_assign(p_previous_test, result_addr);
+ }
+ codegen.generator->pop_temporary(); // Remove temp result addr.
+
+ return p_previous_test;
} break;
case GDScriptParser::PatternNode::PT_ARRAY: {
- int slevel = p_stack_level;
-
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
// Get array type into constant map.
- int array_type_addr = codegen.get_constant_pos(Variant::ARRAY);
+ GDScriptCodeGenerator::Address array_type_addr = codegen.add_constant((int)Variant::ARRAY);
+
+ // Equality is always a boolean.
+ GDScriptDataType temp_type;
+ temp_type.has_type = true;
+ temp_type.kind = GDScriptDataType::BUILTIN;
+ temp_type.builtin_type = Variant::BOOL;
// Check type equality.
- int equality_addr = slevel++;
- equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(slevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_type_addr);
- codegen.opcodes.push_back(array_type_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if not the same type.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ GDScriptCodeGenerator::Address result_addr = codegen.add_temporary(temp_type);
+ codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, array_type_addr);
+ codegen.generator->write_and_left_operand(result_addr);
// Store pattern length in constant map.
- int array_length_addr = codegen.get_constant_pos(p_pattern->rest_used ? p_pattern->array.size() - 1 : p_pattern->array.size());
+ GDScriptCodeGenerator::Address array_length_addr = codegen.add_constant(p_pattern->rest_used ? p_pattern->array.size() - 1 : p_pattern->array.size());
// Get value length.
- int value_length_addr = slevel++;
- codegen.alloc_stack(slevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::LEN);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(p_value_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(value_length_addr); // Address to result.
+ temp_type.builtin_type = Variant::INT;
+ GDScriptCodeGenerator::Address value_length_addr = codegen.add_temporary(temp_type);
+ Vector<GDScriptCodeGenerator::Address> len_args;
+ len_args.push_back(p_value_addr);
+ codegen.generator->write_call_builtin(value_length_addr, GDScriptFunctions::LEN, len_args);
// Test length compatibility.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL);
- codegen.opcodes.push_back(value_length_addr);
- codegen.opcodes.push_back(array_length_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if length is not compatible.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ temp_type.builtin_type = Variant::BOOL;
+ GDScriptCodeGenerator::Address length_compat_addr = codegen.add_temporary(temp_type);
+ codegen.generator->write_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, array_length_addr);
+ codegen.generator->write_and_right_operand(length_compat_addr);
+
+ // AND type and length check.
+ codegen.generator->write_end_and(result_addr);
+
+ // Remove length temporaries.
+ codegen.generator->pop_temporary();
+ codegen.generator->pop_temporary();
+
+ // If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
+ if (p_is_nested) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_and_right_operand(result_addr);
+ codegen.generator->write_end_and(p_previous_test);
+ } else if (!p_is_first) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_or_right_operand(result_addr);
+ codegen.generator->write_end_or(p_previous_test);
+ } else {
+ // Just assign this value to the accumulator temporary.
+ codegen.generator->write_assign(p_previous_test, result_addr);
+ }
+ codegen.generator->pop_temporary(); // Remove temp result addr.
+
+ // Create temporaries outside the loop so they can be reused.
+ GDScriptCodeGenerator::Address element_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address element_type_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address test_addr = p_previous_test;
// Evaluate element by element.
for (int i = 0; i < p_pattern->array.size(); i++) {
@@ -1596,494 +1161,461 @@ Error GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, const GDScriptPar
break;
}
- int stlevel = p_stack_level;
- Vector<int> element_block_patches; // I want to internal patterns try the next element instead of going to the block.
+ // Use AND here too, as we don't want to be checking elements if previous test failed (which means this might be an invalid get).
+ codegen.generator->write_and_left_operand(test_addr);
+
// Add index to constant map.
- int index_addr = codegen.get_constant_pos(i);
+ GDScriptCodeGenerator::Address index_addr = codegen.add_constant(i);
// Get the actual element from the user-sent array.
- int element_addr = stlevel++;
- codegen.alloc_stack(stlevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
- codegen.opcodes.push_back(p_value_addr); // Source.
- codegen.opcodes.push_back(index_addr); // Index.
- codegen.opcodes.push_back(element_addr); // Destination.
+ codegen.generator->write_get(element_addr, index_addr, p_value_addr);
// Also get type of element.
- int element_type_addr = stlevel++;
- element_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(stlevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(element_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(element_type_addr); // Address to result.
+ Vector<GDScriptCodeGenerator::Address> typeof_args;
+ typeof_args.push_back(element_addr);
+ codegen.generator->write_call_builtin(element_type_addr, GDScriptFunctions::TYPE_OF, typeof_args);
// Try the pattern inside the element.
- Error err = _parse_match_pattern(codegen, p_pattern->array[i], stlevel, element_addr, element_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
- if (err != OK) {
- return err;
+ test_addr = _parse_match_pattern(codegen, r_error, p_pattern->array[i], element_addr, element_type_addr, p_previous_test, false, true);
+ if (r_error != OK) {
+ return GDScriptCodeGenerator::Address();
}
- // Patch jumps to block to try the next element.
- for (int j = 0; j < element_block_patches.size(); j++) {
- codegen.opcodes.write[element_block_patches[j]] = codegen.opcodes.size();
- }
+ codegen.generator->write_and_right_operand(test_addr);
+ codegen.generator->write_end_and(test_addr);
}
+ // Remove element temporaries.
+ codegen.generator->pop_temporary();
+ codegen.generator->pop_temporary();
- // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
- // Also here for the case of empty arrays.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- r_block_patch_address.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ return test_addr;
} break;
case GDScriptParser::PatternNode::PT_DICTIONARY: {
- int slevel = p_stack_level;
-
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
// Get dictionary type into constant map.
- int dict_type_addr = codegen.get_constant_pos(Variant::DICTIONARY);
+ GDScriptCodeGenerator::Address dict_type_addr = codegen.add_constant((int)Variant::DICTIONARY);
+
+ // Equality is always a boolean.
+ GDScriptDataType temp_type;
+ temp_type.has_type = true;
+ temp_type.kind = GDScriptDataType::BUILTIN;
+ temp_type.builtin_type = Variant::BOOL;
// Check type equality.
- int equality_addr = slevel++;
- equality_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(slevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(Variant::OP_EQUAL);
- codegen.opcodes.push_back(p_type_addr);
- codegen.opcodes.push_back(dict_type_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if not the same type.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ GDScriptCodeGenerator::Address result_addr = codegen.add_temporary(temp_type);
+ codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, dict_type_addr);
+ codegen.generator->write_and_left_operand(result_addr);
// Store pattern length in constant map.
- int dict_length_addr = codegen.get_constant_pos(p_pattern->rest_used ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
+ GDScriptCodeGenerator::Address dict_length_addr = codegen.add_constant(p_pattern->rest_used ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
// Get user's dictionary length.
- int value_length_addr = slevel++;
- codegen.alloc_stack(slevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::LEN);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(p_value_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(value_length_addr); // Address to result.
+ temp_type.builtin_type = Variant::INT;
+ GDScriptCodeGenerator::Address value_length_addr = codegen.add_temporary(temp_type);
+ Vector<GDScriptCodeGenerator::Address> func_args;
+ func_args.push_back(p_value_addr);
+ codegen.generator->write_call_builtin(value_length_addr, GDScriptFunctions::LEN, func_args);
// Test length compatibility.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR);
- codegen.opcodes.push_back(p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL);
- codegen.opcodes.push_back(value_length_addr);
- codegen.opcodes.push_back(dict_length_addr);
- codegen.opcodes.push_back(equality_addr); // Address to result.
-
- // Jump away if length is not compatible.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(equality_addr);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ temp_type.builtin_type = Variant::BOOL;
+ GDScriptCodeGenerator::Address length_compat_addr = codegen.add_temporary(temp_type);
+ codegen.generator->write_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, dict_length_addr);
+ codegen.generator->write_and_right_operand(length_compat_addr);
+
+ // AND type and length check.
+ codegen.generator->write_end_and(result_addr);
+
+ // Remove length temporaries.
+ codegen.generator->pop_temporary();
+ codegen.generator->pop_temporary();
+
+ // If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
+ if (p_is_nested) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_and_right_operand(result_addr);
+ codegen.generator->write_end_and(p_previous_test);
+ } else if (!p_is_first) {
+ // Use the previous value as target, since we only need one temporary variable.
+ codegen.generator->write_or_right_operand(result_addr);
+ codegen.generator->write_end_or(p_previous_test);
+ } else {
+ // Just assign this value to the accumulator temporary.
+ codegen.generator->write_assign(p_previous_test, result_addr);
+ }
+ codegen.generator->pop_temporary(); // Remove temp result addr.
+
+ // Create temporaries outside the loop so they can be reused.
+ temp_type.builtin_type = Variant::BOOL;
+ GDScriptCodeGenerator::Address test_result = codegen.add_temporary(temp_type);
+ GDScriptCodeGenerator::Address element_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address element_type_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address test_addr = p_previous_test;
// Evaluate element by element.
for (int i = 0; i < p_pattern->dictionary.size(); i++) {
const GDScriptParser::PatternNode::Pair &element = p_pattern->dictionary[i];
if (element.value_pattern && element.value_pattern->pattern_type == GDScriptParser::PatternNode::PT_REST) {
// Ignore rest pattern.
- continue;
+ break;
}
- int stlevel = p_stack_level;
- Vector<int> element_block_patches; // I want to internal patterns try the next element instead of going to the block.
+
+ // Use AND here too, as we don't want to be checking elements if previous test failed (which means this might be an invalid get).
+ codegen.generator->write_and_left_operand(test_addr);
// Get the pattern key.
- int pattern_key_addr = _parse_expression(codegen, element.key, stlevel);
- if (pattern_key_addr < 0) {
- return ERR_PARSE_ERROR;
- }
- if ((pattern_key_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- stlevel++;
- codegen.alloc_stack(stlevel);
+ GDScriptCodeGenerator::Address pattern_key_addr = _parse_expression(codegen, r_error, element.key);
+ if (r_error) {
+ return GDScriptCodeGenerator::Address();
}
- // Create stack slot for test result.
- int test_result = stlevel++;
- test_result |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(stlevel);
-
- // Check if pattern key exists in user's dictionary.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_RETURN);
- codegen.opcodes.push_back(1); // Argument count.
- codegen.opcodes.push_back(p_value_addr); // Base (user dictionary).
- codegen.opcodes.push_back(codegen.get_name_map_pos("has")); // Function name.
- codegen.opcodes.push_back(pattern_key_addr); // Argument (pattern key).
- codegen.opcodes.push_back(test_result); // Return address.
-
- // Jump away if key doesn't exist.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(test_result);
- r_patch_addresses.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ // Check if pattern key exists in user's dictionary. This will be AND-ed with next result.
+ func_args.clear();
+ func_args.push_back(pattern_key_addr);
+ codegen.generator->write_call(test_result, p_value_addr, "has", func_args);
if (element.value_pattern != nullptr) {
+ // Use AND here too, as we don't want to be checking elements if previous test failed (which means this might be an invalid get).
+ codegen.generator->write_and_left_operand(test_result);
+
// Get actual value from user dictionary.
- int value_addr = stlevel++;
- codegen.alloc_stack(stlevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
- codegen.opcodes.push_back(p_value_addr); // Source.
- codegen.opcodes.push_back(pattern_key_addr); // Index.
- codegen.opcodes.push_back(value_addr); // Destination.
+ codegen.generator->write_get(element_addr, pattern_key_addr, p_value_addr);
// Also get type of value.
- int value_type_addr = stlevel++;
- value_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(stlevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(value_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(value_type_addr); // Address to result.
+ func_args.clear();
+ func_args.push_back(element_addr);
+ codegen.generator->write_call_builtin(element_type_addr, GDScriptFunctions::TYPE_OF, func_args);
// Try the pattern inside the value.
- Error err = _parse_match_pattern(codegen, element.value_pattern, stlevel, value_addr, value_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
- if (err != OK) {
- return err;
+ test_addr = _parse_match_pattern(codegen, r_error, element.value_pattern, element_addr, element_type_addr, test_addr, false, true);
+ if (r_error != OK) {
+ return GDScriptCodeGenerator::Address();
}
+ codegen.generator->write_and_right_operand(test_addr);
+ codegen.generator->write_end_and(test_addr);
}
- // Patch jumps to block to try the next element.
- for (int j = 0; j < element_block_patches.size(); j++) {
- codegen.opcodes.write[element_block_patches[j]] = codegen.opcodes.size();
+ codegen.generator->write_and_right_operand(test_addr);
+ codegen.generator->write_end_and(test_addr);
+
+ // Remove pattern key temporary.
+ if (pattern_key_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
}
- // Jump to the actual block since it matches. This is needed to take multi-pattern into account.
- // Also here for the case of empty dictionaries.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- r_block_patch_address.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ // Remove element temporaries.
+ codegen.generator->pop_temporary();
+ codegen.generator->pop_temporary();
+ codegen.generator->pop_temporary();
+ return test_addr;
} break;
case GDScriptParser::PatternNode::PT_REST:
// Do nothing.
+ return p_previous_test;
break;
+ case GDScriptParser::PatternNode::PT_BIND: {
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
+ // Get the bind address.
+ GDScriptCodeGenerator::Address bind = codegen.locals[p_pattern->bind->name];
+
+ // Assign value to bound variable.
+ codegen.generator->write_assign(bind, p_value_addr);
+ }
+ [[fallthrough]]; // Act like matching anything too.
case GDScriptParser::PatternNode::PT_WILDCARD:
- // This matches anything so just do the jump.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- r_block_patch_address.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be replaced.
+ // If this is a fall through we don't want to do this again.
+ if (p_pattern->pattern_type != GDScriptParser::PatternNode::PT_BIND) {
+ if (p_is_nested) {
+ codegen.generator->write_and_left_operand(p_previous_test);
+ } else if (!p_is_first) {
+ codegen.generator->write_or_left_operand(p_previous_test);
+ }
+ }
+ // This matches anything so just do the same as `if(true)`.
+ // If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
+ if (p_is_nested) {
+ // Use the operator with the `true` constant so it works as always matching.
+ GDScriptCodeGenerator::Address constant = codegen.add_constant(true);
+ codegen.generator->write_and_right_operand(constant);
+ codegen.generator->write_end_and(p_previous_test);
+ } else if (!p_is_first) {
+ // Use the operator with the `true` constant so it works as always matching.
+ GDScriptCodeGenerator::Address constant = codegen.add_constant(true);
+ codegen.generator->write_or_right_operand(constant);
+ codegen.generator->write_end_or(p_previous_test);
+ } else {
+ // Just assign this value to the accumulator temporary.
+ codegen.generator->write_assign_true(p_previous_test);
+ }
+ return p_previous_test;
}
- return OK;
+ ERR_FAIL_V_MSG(p_previous_test, "Reaching the end of pattern compilation without matching a pattern.");
}
-Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) {
- codegen.push_stack_identifiers();
- int new_identifiers = 0;
- codegen.current_line = p_block->start_line;
+void GDScriptCompiler::_add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block) {
+ for (int i = 0; i < p_block->locals.size(); i++) {
+ if (p_block->locals[i].type == GDScriptParser::SuiteNode::Local::PARAMETER || p_block->locals[i].type == GDScriptParser::SuiteNode::Local::FOR_VARIABLE) {
+ // Parameters are added directly from function and loop variables are declared explicitly.
+ continue;
+ }
+ codegen.add_local(p_block->locals[i].name, _gdtype_from_datatype(p_block->locals[i].get_datatype()));
+ }
+}
+
+Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals) {
+ Error error = OK;
+ GDScriptCodeGenerator *gen = codegen.generator;
+
+ codegen.start_block();
+
+ if (p_add_locals) {
+ _add_locals_in_block(codegen, p_block);
+ }
for (int i = 0; i < p_block->statements.size(); i++) {
const GDScriptParser::Node *s = p_block->statements[i];
#ifdef DEBUG_ENABLED
// Add a newline before each statement, since the debugger needs those.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
- codegen.opcodes.push_back(s->start_line);
- codegen.current_line = s->start_line;
+ gen->write_newline(s->start_line);
#endif
switch (s->type) {
case GDScriptParser::Node::MATCH: {
const GDScriptParser::MatchNode *match = static_cast<const GDScriptParser::MatchNode *>(s);
- int slevel = p_stack_level;
+ gen->start_match();
+ codegen.start_block();
- // First, let's save the addres of the value match.
- int temp_addr = _parse_expression(codegen, match->test, slevel);
- if (temp_addr < 0) {
- return ERR_PARSE_ERROR;
- }
- if ((temp_addr >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
- slevel++;
- codegen.alloc_stack(slevel);
+ // Evaluate the match expression.
+ GDScriptCodeGenerator::Address value = _parse_expression(codegen, error, match->test);
+ if (error) {
+ return error;
}
// Then, let's save the type of the value in the stack too, so we can reuse for later comparisons.
- int type_addr = slevel++;
- type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
- codegen.alloc_stack(slevel);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
- codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
- codegen.opcodes.push_back(1); // One argument.
- codegen.opcodes.push_back(temp_addr); // Argument is the value we want to test.
- codegen.opcodes.push_back(type_addr); // Address to result.
-
- Vector<int> patch_match_end; // Will patch the jump to the end of match.
+ GDScriptCodeGenerator::Address type = codegen.add_temporary();
+ Vector<GDScriptCodeGenerator::Address> typeof_args;
+ typeof_args.push_back(value);
+ gen->write_call_builtin(type, GDScriptFunctions::TYPE_OF, typeof_args);
// Now we can actually start testing.
// For each branch.
for (int j = 0; j < match->branches.size(); j++) {
+ if (j > 0) {
+ // Use `else` to not check the next branch after matching.
+ gen->write_else();
+ }
+
const GDScriptParser::MatchBranchNode *branch = match->branches[j];
- int bound_variables = 0;
- codegen.push_stack_identifiers(); // Create an extra block around for binds.
+ gen->start_match_branch(); // Need so lower level code can patch 'continue' jumps.
+ codegen.start_block(); // Create an extra block around for binds.
+
+ // Add locals in block before patterns, so temporaries don't use the stack address for binds.
+ _add_locals_in_block(codegen, branch->block);
#ifdef DEBUG_ENABLED
// Add a newline before each branch, since the debugger needs those.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
- codegen.opcodes.push_back(s->start_line);
- codegen.current_line = s->start_line;
+ gen->write_newline(branch->start_line);
#endif
- Vector<int> patch_addrs; // Will patch with end of pattern to jump.
- Vector<int> block_patch_addrs; // Will patch with start of block to jump.
-
// For each pattern in branch.
+ GDScriptCodeGenerator::Address pattern_result = codegen.add_temporary();
for (int k = 0; k < branch->patterns.size(); k++) {
- if (k > 0) {
- // Patch jumps per pattern to allow for multipattern. If a pattern fails it just tries the next.
- for (int l = 0; l < patch_addrs.size(); l++) {
- codegen.opcodes.write[patch_addrs[l]] = codegen.opcodes.size();
- }
- patch_addrs.clear();
- }
- Error err = _parse_match_pattern(codegen, branch->patterns[k], slevel, temp_addr, type_addr, bound_variables, patch_addrs, block_patch_addrs);
- if (err != OK) {
- return err;
+ pattern_result = _parse_match_pattern(codegen, error, branch->patterns[k], value, type, pattern_result, k == 0, false);
+ if (error != OK) {
+ return error;
}
}
- // Patch jumps to the block.
- for (int k = 0; k < block_patch_addrs.size(); k++) {
- codegen.opcodes.write[block_patch_addrs[k]] = codegen.opcodes.size();
- }
- // Leave space for bound variables.
- slevel += bound_variables;
- codegen.alloc_stack(slevel);
+ // Check if pattern did match.
+ gen->write_if(pattern_result);
- // Parse the branch block.
- _parse_block(codegen, branch->block, slevel, p_break_addr, p_continue_addr);
+ // Remove the result from stack.
+ gen->pop_temporary();
- // Jump to end of match.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- patch_match_end.push_back(codegen.opcodes.size());
- codegen.opcodes.push_back(0); // Will be patched.
-
- // Patch the addresses of last pattern to jump to the end of the branch, into the next one.
- for (int k = 0; k < patch_addrs.size(); k++) {
- codegen.opcodes.write[patch_addrs[k]] = codegen.opcodes.size();
+ // Parse the branch block.
+ error = _parse_block(codegen, branch->block, false); // Don't add locals again.
+ if (error) {
+ return error;
}
- codegen.pop_stack_identifiers(); // Get out of extra block.
+ codegen.end_block(); // Get out of extra block.
+ }
+
+ // End all nested `if`s.
+ for (int j = 0; j < match->branches.size(); j++) {
+ gen->write_endif();
}
- // Patch the addresses to jump to the end of the match statement.
- for (int j = 0; j < patch_match_end.size(); j++) {
- codegen.opcodes.write[patch_match_end[j]] = codegen.opcodes.size();
+
+ gen->pop_temporary();
+
+ if (value.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
- } break;
+ gen->end_match();
+ } break;
case GDScriptParser::Node::IF: {
const GDScriptParser::IfNode *if_n = static_cast<const GDScriptParser::IfNode *>(s);
- int ret2 = _parse_expression(codegen, if_n->condition, p_stack_level, false);
- if (ret2 < 0) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address condition = _parse_expression(codegen, error, if_n->condition);
+ if (error) {
+ return error;
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(ret2);
- int else_addr = codegen.opcodes.size();
- codegen.opcodes.push_back(0); //temporary
+ gen->write_if(condition);
+
+ if (condition.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
- Error err = _parse_block(codegen, if_n->true_block, p_stack_level, p_break_addr, p_continue_addr);
- if (err) {
- return err;
+ error = _parse_block(codegen, if_n->true_block);
+ if (error) {
+ return error;
}
if (if_n->false_block) {
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- int end_addr = codegen.opcodes.size();
- codegen.opcodes.push_back(0);
- codegen.opcodes.write[else_addr] = codegen.opcodes.size();
-
- Error err2 = _parse_block(codegen, if_n->false_block, p_stack_level, p_break_addr, p_continue_addr);
- if (err2) {
- return err2;
- }
+ gen->write_else();
- codegen.opcodes.write[end_addr] = codegen.opcodes.size();
- } else {
- //end without else
- codegen.opcodes.write[else_addr] = codegen.opcodes.size();
+ error = _parse_block(codegen, if_n->false_block);
+ if (error) {
+ return error;
+ }
}
+ gen->write_endif();
} break;
case GDScriptParser::Node::FOR: {
const GDScriptParser::ForNode *for_n = static_cast<const GDScriptParser::ForNode *>(s);
- int slevel = p_stack_level;
- int iter_stack_pos = slevel;
- int iterator_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- int counter_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- int container_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- codegen.alloc_stack(slevel);
-
- codegen.push_stack_identifiers();
- codegen.add_stack_identifier(for_n->variable->name, iter_stack_pos);
-
- int ret2 = _parse_expression(codegen, for_n->list, slevel, false);
- if (ret2 < 0) {
- return ERR_COMPILATION_FAILED;
- }
-
- //assign container
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
- codegen.opcodes.push_back(container_pos);
- codegen.opcodes.push_back(ret2);
-
- //begin loop
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE_BEGIN);
- codegen.opcodes.push_back(counter_pos);
- codegen.opcodes.push_back(container_pos);
- codegen.opcodes.push_back(codegen.opcodes.size() + 4);
- codegen.opcodes.push_back(iterator_pos);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next
- codegen.opcodes.push_back(codegen.opcodes.size() + 8);
- //break loop
- int break_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); //skip code for next
- codegen.opcodes.push_back(0); //skip code for next
- //next loop
- int continue_pos = codegen.opcodes.size();
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ITERATE);
- codegen.opcodes.push_back(counter_pos);
- codegen.opcodes.push_back(container_pos);
- codegen.opcodes.push_back(break_pos);
- codegen.opcodes.push_back(iterator_pos);
-
- Error err = _parse_block(codegen, for_n->loop, slevel, break_pos, continue_pos);
- if (err) {
- return err;
- }
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(continue_pos);
- codegen.opcodes.write[break_pos + 1] = codegen.opcodes.size();
-
- codegen.pop_stack_identifiers();
+ codegen.start_block();
+ GDScriptCodeGenerator::Address iterator = codegen.add_local(for_n->variable->name, _gdtype_from_datatype(for_n->variable->get_datatype()));
+
+ GDScriptCodeGenerator::Address list = _parse_expression(codegen, error, for_n->list);
+ if (error) {
+ return error;
+ }
+
+ gen->write_for(iterator, list);
+
+ error = _parse_block(codegen, for_n->loop);
+ if (error) {
+ return error;
+ }
+
+ gen->write_endfor();
+
+ if (list.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
+
+ codegen.end_block();
} break;
case GDScriptParser::Node::WHILE: {
const GDScriptParser::WhileNode *while_n = static_cast<const GDScriptParser::WhileNode *>(s);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(codegen.opcodes.size() + 3);
- int break_addr = codegen.opcodes.size();
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(0);
- int continue_addr = codegen.opcodes.size();
-
- int ret2 = _parse_expression(codegen, while_n->condition, p_stack_level, false);
- if (ret2 < 0) {
- return ERR_PARSE_ERROR;
+
+ gen->start_while_condition();
+
+ GDScriptCodeGenerator::Address condition = _parse_expression(codegen, error, while_n->condition);
+ if (error) {
+ return error;
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
- codegen.opcodes.push_back(ret2);
- codegen.opcodes.push_back(break_addr);
- Error err = _parse_block(codegen, while_n->loop, p_stack_level, break_addr, continue_addr);
- if (err) {
- return err;
+
+ gen->write_while(condition);
+
+ if (condition.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(continue_addr);
- codegen.opcodes.write[break_addr + 1] = codegen.opcodes.size();
+ error = _parse_block(codegen, while_n->loop);
+ if (error) {
+ return error;
+ }
+ gen->write_endwhile();
} break;
case GDScriptParser::Node::BREAK: {
- if (p_break_addr < 0) {
- _set_error("'break'' not within loop", s);
- return ERR_COMPILATION_FAILED;
- }
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(p_break_addr);
-
+ gen->write_break();
} break;
case GDScriptParser::Node::CONTINUE: {
- if (p_continue_addr < 0) {
- _set_error("'continue' not within loop", s);
- return ERR_COMPILATION_FAILED;
+ const GDScriptParser::ContinueNode *cont = static_cast<const GDScriptParser::ContinueNode *>(s);
+ if (cont->is_for_match) {
+ gen->write_continue_match();
+ } else {
+ gen->write_continue();
}
-
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
- codegen.opcodes.push_back(p_continue_addr);
-
} break;
case GDScriptParser::Node::RETURN: {
const GDScriptParser::ReturnNode *return_n = static_cast<const GDScriptParser::ReturnNode *>(s);
- int ret2;
+
+ GDScriptCodeGenerator::Address return_value;
if (return_n->return_value != nullptr) {
- ret2 = _parse_expression(codegen, return_n->return_value, p_stack_level, false);
- if (ret2 < 0) {
- return ERR_PARSE_ERROR;
+ return_value = _parse_expression(codegen, error, return_n->return_value);
+ if (error) {
+ return error;
}
-
- } else {
- ret2 = GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_RETURN);
- codegen.opcodes.push_back(ret2);
-
+ gen->write_return(return_value);
+ if (return_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
} break;
case GDScriptParser::Node::ASSERT: {
#ifdef DEBUG_ENABLED
- // try subblocks
-
const GDScriptParser::AssertNode *as = static_cast<const GDScriptParser::AssertNode *>(s);
- int ret2 = _parse_expression(codegen, as->condition, p_stack_level, false);
- if (ret2 < 0) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address condition = _parse_expression(codegen, error, as->condition);
+ if (error) {
+ return error;
}
- int message_ret = 0;
+ GDScriptCodeGenerator::Address message;
+
if (as->message) {
- message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
- if (message_ret < 0) {
- return ERR_PARSE_ERROR;
+ message = _parse_expression(codegen, error, as->message);
+ if (error) {
+ return error;
}
}
+ gen->write_assert(condition, message);
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
- codegen.opcodes.push_back(ret2);
- codegen.opcodes.push_back(message_ret);
+ if (condition.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
+ if (message.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
+ }
#endif
} break;
case GDScriptParser::Node::BREAKPOINT: {
#ifdef DEBUG_ENABLED
- // try subblocks
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_BREAKPOINT);
+ gen->write_breakpoint();
#endif
} break;
case GDScriptParser::Node::VARIABLE: {
const GDScriptParser::VariableNode *lv = static_cast<const GDScriptParser::VariableNode *>(s);
-
- // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
- //
- //if (_is_class_member_property(codegen, lv->name)) {
- // _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
- // return ERR_ALREADY_EXISTS;
- //}
-
- codegen.add_stack_identifier(lv->identifier->name, p_stack_level++);
- codegen.alloc_stack(p_stack_level);
- new_identifiers++;
+ // Should be already in stack when the block began.
+ GDScriptCodeGenerator::Address local = codegen.locals[lv->identifier->name];
if (lv->initializer != nullptr) {
- int dst_address = codegen.stack_identifiers[lv->identifier->name];
- dst_address |= GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS;
-
- int src_address = _parse_expression(codegen, lv->initializer, p_stack_level);
- if (src_address < 0) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address src_address = _parse_expression(codegen, error, lv->initializer);
+ if (error) {
+ return error;
}
- if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(lv->get_datatype()), lv->initializer->get_datatype())) {
- return ERR_PARSE_ERROR;
+ gen->write_assign(local, src_address);
+ if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
}
} break;
@@ -2094,281 +1626,159 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
_set_error("Local constant must have a constant value as initializer.", lc->initializer);
return ERR_PARSE_ERROR;
}
- codegen.local_named_constants[lc->identifier->name] = codegen.get_constant_pos(lc->initializer->reduced_value);
+
+ codegen.add_local_constant(lc->identifier->name, lc->initializer->reduced_value);
} break;
case GDScriptParser::Node::PASS:
// Nothing to do.
break;
default: {
- //expression
+ // Expression.
if (s->is_expression()) {
- int ret2 = _parse_expression(codegen, static_cast<const GDScriptParser::ExpressionNode *>(s), p_stack_level, true);
- if (ret2 < 0) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address expr = _parse_expression(codegen, error, static_cast<const GDScriptParser::ExpressionNode *>(s), true);
+ if (error) {
+ return error;
+ }
+ if (expr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
} else {
- ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Bug in bytecode compiler, unexpected node in parse tree while parsing statement."); //unreachable code
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Bug in bytecode compiler, unexpected node in parse tree while parsing statement."); // Unreachable code.
}
} break;
}
}
- codegen.pop_stack_identifiers();
+ codegen.end_block();
return OK;
}
Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) {
- Vector<int> bytecode;
+ Error error = OK;
CodeGen codegen;
+ codegen.generator = memnew(GDScriptByteCodeGenerator);
codegen.class_node = p_class;
codegen.script = p_script;
codegen.function_node = p_func;
- codegen.stack_max = 0;
- codegen.current_line = 0;
- codegen.call_max = 0;
- codegen.debug_stack = EngineDebugger::is_active();
- Vector<StringName> argnames;
- int stack_level = 0;
+ StringName func_name;
+ bool is_static = false;
+ MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+ GDScriptDataType return_type;
+ return_type.has_type = true;
+ return_type.kind = GDScriptDataType::BUILTIN;
+ return_type.builtin_type = Variant::NIL;
+
+ if (p_func) {
+ func_name = p_func->identifier->name;
+ is_static = p_func->is_static;
+ rpc_mode = p_func->rpc_mode;
+ return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script);
+ } else {
+ if (p_for_ready) {
+ func_name = "_ready";
+ } else {
+ func_name = "@implicit_new";
+ }
+ }
+
+ codegen.function_name = func_name;
+ codegen.generator->write_start(p_script, func_name, is_static, rpc_mode, return_type);
+
int optional_parameters = 0;
if (p_func) {
for (int i = 0; i < p_func->parameters.size(); i++) {
- // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
- //
- //if (_is_class_member_property(p_script, p_func->arguments[i])) {
- // _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
- // return ERR_ALREADY_EXISTS;
- //}
-
- codegen.add_stack_identifier(p_func->parameters[i]->identifier->name, i);
-#ifdef TOOLS_ENABLED
- argnames.push_back(p_func->parameters[i]->identifier->name);
-#endif
+ const GDScriptParser::ParameterNode *parameter = p_func->parameters[i];
+ GDScriptDataType par_type = _gdtype_from_datatype(parameter->get_datatype(), p_script);
+ uint32_t par_addr = codegen.generator->add_parameter(parameter->identifier->name, parameter->default_value != nullptr, par_type);
+ codegen.parameters[parameter->identifier->name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::FUNCTION_PARAMETER, par_addr, par_type);
+
if (p_func->parameters[i]->default_value != nullptr) {
optional_parameters++;
}
}
- stack_level = p_func->parameters.size();
}
- codegen.alloc_stack(stack_level);
-
- /* Parse initializer -if applies- */
-
+ // Parse initializer if applies.
bool is_implicit_initializer = !p_for_ready && !p_func;
bool is_initializer = p_func && String(p_func->identifier->name) == GDScriptLanguage::get_singleton()->strings._init;
+ bool is_for_ready = p_for_ready || (p_func && String(p_func->identifier->name) == "_ready");
- if (is_implicit_initializer) {
+ if (is_implicit_initializer || is_for_ready) {
// Initialize class fields.
for (int i = 0; i < p_class->members.size(); i++) {
if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) {
continue;
}
const GDScriptParser::VariableNode *field = p_class->members[i].variable;
- if (field->onready) {
+ if (field->onready != is_for_ready) {
// Only initialize in _ready.
continue;
}
if (field->initializer) {
// Emit proper line change.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
- codegen.opcodes.push_back(field->initializer->start_line);
-
- int src_address = _parse_expression(codegen, field->initializer, stack_level, false, true);
- if (src_address < 0) {
- return ERR_PARSE_ERROR;
- }
- int dst_address = codegen.script->member_indices[field->identifier->name].index;
- dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
-
- if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
- return ERR_PARSE_ERROR;
- }
- }
- }
- }
-
- if (p_for_ready || (p_func && String(p_func->identifier->name) == "_ready")) {
- // Initialize class fields on ready.
- for (int i = 0; i < p_class->members.size(); i++) {
- if (p_class->members[i].type != GDScriptParser::ClassNode::Member::VARIABLE) {
- continue;
- }
- const GDScriptParser::VariableNode *field = p_class->members[i].variable;
- if (!field->onready) {
- continue;
- }
-
- if (field->initializer) {
- // Emit proper line change.
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_LINE);
- codegen.opcodes.push_back(field->initializer->start_line);
+ codegen.generator->write_newline(field->initializer->start_line);
- int src_address = _parse_expression(codegen, field->initializer, stack_level, false, true);
- if (src_address < 0) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address src_address = _parse_expression(codegen, error, field->initializer, false, true);
+ if (error) {
+ memdelete(codegen.generator);
+ return error;
}
- int dst_address = codegen.script->member_indices[field->identifier->name].index;
- dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
+ GDScriptCodeGenerator::Address dst_address(GDScriptCodeGenerator::Address::MEMBER, codegen.script->member_indices[field->identifier->name].index, _gdtype_from_datatype(field->get_datatype()));
- if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
- return ERR_PARSE_ERROR;
+ codegen.generator->write_assign(dst_address, src_address);
+ if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
}
}
}
- /* Parse default argument code -if applies- */
-
- Vector<int> defarg_addr;
- StringName func_name;
-
+ // Parse default argument code if applies.
if (p_func) {
if (optional_parameters > 0) {
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT);
- defarg_addr.push_back(codegen.opcodes.size());
+ codegen.generator->start_parameters();
for (int i = p_func->parameters.size() - optional_parameters; i < p_func->parameters.size(); i++) {
- int src_addr = _parse_expression(codegen, p_func->parameters[i]->default_value, stack_level, true);
- if (src_addr < 0) {
- return ERR_PARSE_ERROR;
+ const GDScriptParser::ParameterNode *parameter = p_func->parameters[i];
+ GDScriptCodeGenerator::Address src_addr = _parse_expression(codegen, error, parameter->default_value, true);
+ if (error) {
+ memdelete(codegen.generator);
+ return error;
}
- int dst_addr = codegen.stack_identifiers[p_func->parameters[i]->identifier->name] | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
- if (!_generate_typed_assign(codegen, src_addr, dst_addr, _gdtype_from_datatype(p_func->parameters[i]->get_datatype()), p_func->parameters[i]->default_value->get_datatype())) {
- return ERR_PARSE_ERROR;
+ GDScriptCodeGenerator::Address dst_addr = codegen.parameters[parameter->identifier->name];
+ codegen.generator->write_assign(dst_addr, src_addr);
+ if (src_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ codegen.generator->pop_temporary();
}
- defarg_addr.push_back(codegen.opcodes.size());
}
- defarg_addr.invert();
+ codegen.generator->end_parameters();
}
- func_name = p_func->identifier->name;
- codegen.function_name = func_name;
- Error err = _parse_block(codegen, p_func->body, stack_level);
+ Error err = _parse_block(codegen, p_func->body);
if (err) {
+ memdelete(codegen.generator);
return err;
}
-
- } else {
- if (p_for_ready) {
- func_name = "_ready";
- } else {
- func_name = "@implicit_new";
- }
- }
-
- codegen.function_name = func_name;
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_END);
-
- /*
- if (String(p_func->name)=="") { //initializer func
- gdfunc = &p_script->initializer;
- */
- //} else { //regular func
- p_script->member_functions[func_name] = memnew(GDScriptFunction);
- GDScriptFunction *gdfunc = p_script->member_functions[func_name];
- //}
-
- if (p_func) {
- gdfunc->_static = p_func->is_static;
- gdfunc->rpc_mode = p_func->rpc_mode;
- gdfunc->argument_types.resize(p_func->parameters.size());
- for (int i = 0; i < p_func->parameters.size(); i++) {
- gdfunc->argument_types.write[i] = _gdtype_from_datatype(p_func->parameters[i]->get_datatype());
- }
- gdfunc->return_type = _gdtype_from_datatype(p_func->get_datatype());
- } else {
- gdfunc->_static = false;
- gdfunc->rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
- gdfunc->return_type = GDScriptDataType();
- gdfunc->return_type.has_type = true;
- gdfunc->return_type.kind = GDScriptDataType::BUILTIN;
- gdfunc->return_type.builtin_type = Variant::NIL;
- }
-
-#ifdef TOOLS_ENABLED
- gdfunc->arg_names = argnames;
-#endif
- //constants
- if (codegen.constant_map.size()) {
- gdfunc->_constant_count = codegen.constant_map.size();
- gdfunc->constants.resize(codegen.constant_map.size());
- gdfunc->_constants_ptr = gdfunc->constants.ptrw();
- const Variant *K = nullptr;
- while ((K = codegen.constant_map.next(K))) {
- int idx = codegen.constant_map[*K];
- gdfunc->constants.write[idx] = *K;
- }
- } else {
- gdfunc->_constants_ptr = nullptr;
- gdfunc->_constant_count = 0;
- }
- //global names
- if (codegen.name_map.size()) {
- gdfunc->global_names.resize(codegen.name_map.size());
- gdfunc->_global_names_ptr = &gdfunc->global_names[0];
- for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) {
- gdfunc->global_names.write[E->get()] = E->key();
- }
- gdfunc->_global_names_count = gdfunc->global_names.size();
-
- } else {
- gdfunc->_global_names_ptr = nullptr;
- gdfunc->_global_names_count = 0;
- }
-
-#ifdef TOOLS_ENABLED
- // Named globals
- if (codegen.named_globals.size()) {
- gdfunc->named_globals.resize(codegen.named_globals.size());
- gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
- for (int i = 0; i < codegen.named_globals.size(); i++) {
- gdfunc->named_globals.write[i] = codegen.named_globals[i];
- }
- gdfunc->_named_globals_count = gdfunc->named_globals.size();
- }
-#endif
-
- if (codegen.opcodes.size()) {
- gdfunc->code = codegen.opcodes;
- gdfunc->_code_ptr = &gdfunc->code[0];
- gdfunc->_code_size = codegen.opcodes.size();
-
- } else {
- gdfunc->_code_ptr = nullptr;
- gdfunc->_code_size = 0;
}
- if (defarg_addr.size()) {
- gdfunc->default_arguments = defarg_addr;
- gdfunc->_default_arg_count = defarg_addr.size() - 1;
- gdfunc->_default_arg_ptr = &gdfunc->default_arguments[0];
- } else {
- gdfunc->_default_arg_count = 0;
- gdfunc->_default_arg_ptr = nullptr;
- }
-
- gdfunc->_argument_count = p_func ? p_func->parameters.size() : 0;
- gdfunc->_stack_size = codegen.stack_max;
- gdfunc->_call_size = codegen.call_max;
- gdfunc->name = func_name;
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_active()) {
String signature;
- //path
+ // Path.
if (p_script->get_path() != String()) {
signature += p_script->get_path();
}
- //loc
+ // Location.
if (p_func) {
signature += "::" + itos(p_func->body->start_line);
} else {
signature += "::0";
}
- //function and class
+ // Function and class.
if (p_class->identifier) {
signature += "::" + String(p_class->identifier->name) + "." + String(func_name);
@@ -2376,65 +1786,41 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
signature += "::" + String(func_name);
}
- gdfunc->profile.signature = signature;
+ codegen.generator->set_signature(signature);
}
#endif
- gdfunc->_script = p_script;
- gdfunc->source = source;
-
-#ifdef DEBUG_ENABLED
- {
- gdfunc->func_cname = (String(source) + " - " + String(func_name)).utf8();
- gdfunc->_func_cname = gdfunc->func_cname.get_data();
- }
-
-#endif
if (p_func) {
- gdfunc->_initial_line = p_func->start_line;
+ codegen.generator->set_initial_line(p_func->start_line);
#ifdef TOOLS_ENABLED
-
p_script->member_lines[func_name] = p_func->start_line;
#endif
} else {
- gdfunc->_initial_line = 0;
+ codegen.generator->set_initial_line(0);
}
- if (codegen.debug_stack) {
- gdfunc->stack_debug = codegen.stack_debug;
- }
+ GDScriptFunction *gd_function = codegen.generator->write_end();
if (is_initializer) {
- p_script->initializer = gdfunc;
- }
- if (is_implicit_initializer) {
- p_script->implicit_initializer = gdfunc;
+ p_script->initializer = gd_function;
+ } else if (is_implicit_initializer) {
+ p_script->implicit_initializer = gd_function;
}
+ p_script->member_functions[func_name] = gd_function;
+
+ memdelete(codegen.generator);
+
return OK;
}
Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter) {
- Vector<int> bytecode;
+ Error error = OK;
CodeGen codegen;
+ codegen.generator = memnew(GDScriptByteCodeGenerator);
codegen.class_node = p_class;
codegen.script = p_script;
- codegen.function_node = nullptr;
- codegen.stack_max = 0;
- codegen.current_line = 0;
- codegen.call_max = 0;
- codegen.debug_stack = EngineDebugger::is_active();
- Vector<StringName> argnames;
-
- int stack_level = 0;
-
- if (p_is_setter) {
- codegen.add_stack_identifier(p_variable->setter_parameter->name, stack_level++);
- argnames.push_back(p_variable->setter_parameter->name);
- }
-
- codegen.alloc_stack(stack_level);
StringName func_name;
@@ -2443,76 +1829,33 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
} else {
func_name = "@" + p_variable->identifier->name + "_getter";
}
- codegen.function_name = func_name;
- Error err = _parse_block(codegen, p_is_setter ? p_variable->setter : p_variable->getter, stack_level);
- if (err != OK) {
- return err;
+ GDScriptDataType return_type;
+ if (p_is_setter) {
+ return_type.has_type = true;
+ return_type.kind = GDScriptDataType::BUILTIN;
+ return_type.builtin_type = Variant::NIL;
+ } else {
+ return_type = _gdtype_from_datatype(p_variable->get_datatype(), p_script);
}
- codegen.opcodes.push_back(GDScriptFunction::OPCODE_END);
-
- p_script->member_functions[func_name] = memnew(GDScriptFunction);
- GDScriptFunction *gdfunc = p_script->member_functions[func_name];
-
- gdfunc->_static = false;
- gdfunc->rpc_mode = p_variable->rpc_mode;
- gdfunc->argument_types.resize(p_is_setter ? 1 : 0);
- gdfunc->return_type = _gdtype_from_datatype(p_variable->get_datatype());
-#ifdef TOOLS_ENABLED
- gdfunc->arg_names = argnames;
-#endif
+ codegen.generator->write_start(p_script, func_name, false, p_variable->rpc_mode, return_type);
- // TODO: Unify this with function compiler.
- //constants
- if (codegen.constant_map.size()) {
- gdfunc->_constant_count = codegen.constant_map.size();
- gdfunc->constants.resize(codegen.constant_map.size());
- gdfunc->_constants_ptr = gdfunc->constants.ptrw();
- const Variant *K = nullptr;
- while ((K = codegen.constant_map.next(K))) {
- int idx = codegen.constant_map[*K];
- gdfunc->constants.write[idx] = *K;
- }
- } else {
- gdfunc->_constants_ptr = nullptr;
- gdfunc->_constant_count = 0;
+ if (p_is_setter) {
+ uint32_t par_addr = codegen.generator->add_parameter(p_variable->setter_parameter->name, false, _gdtype_from_datatype(p_variable->get_datatype()));
+ codegen.parameters[p_variable->setter_parameter->name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::FUNCTION_PARAMETER, par_addr, _gdtype_from_datatype(p_variable->get_datatype()));
}
- //global names
- if (codegen.name_map.size()) {
- gdfunc->global_names.resize(codegen.name_map.size());
- gdfunc->_global_names_ptr = &gdfunc->global_names[0];
- for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) {
- gdfunc->global_names.write[E->get()] = E->key();
- }
- gdfunc->_global_names_count = gdfunc->global_names.size();
- } else {
- gdfunc->_global_names_ptr = nullptr;
- gdfunc->_global_names_count = 0;
+ error = _parse_block(codegen, p_is_setter ? p_variable->setter : p_variable->getter);
+ if (error) {
+ memdelete(codegen.generator);
+ return error;
}
-#ifdef TOOLS_ENABLED
- // Named globals
- if (codegen.named_globals.size()) {
- gdfunc->named_globals.resize(codegen.named_globals.size());
- gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
- for (int i = 0; i < codegen.named_globals.size(); i++) {
- gdfunc->named_globals.write[i] = codegen.named_globals[i];
- }
- gdfunc->_named_globals_count = gdfunc->named_globals.size();
- }
-#endif
+ GDScriptFunction *gd_function = codegen.generator->write_end();
+
+ p_script->member_functions[func_name] = gd_function;
- gdfunc->code = codegen.opcodes;
- gdfunc->_code_ptr = &gdfunc->code[0];
- gdfunc->_code_size = codegen.opcodes.size();
- gdfunc->_default_arg_count = 0;
- gdfunc->_default_arg_ptr = nullptr;
- gdfunc->_argument_count = argnames.size();
- gdfunc->_stack_size = codegen.stack_max;
- gdfunc->_call_size = codegen.call_max;
- gdfunc->name = func_name;
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_active()) {
String signature;
@@ -2531,29 +1874,15 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
signature += "::" + String(func_name);
}
- gdfunc->profile.signature = signature;
+ codegen.generator->set_signature(signature);
}
#endif
- gdfunc->_script = p_script;
- gdfunc->source = source;
-
-#ifdef DEBUG_ENABLED
-
- {
- gdfunc->func_cname = (String(source) + " - " + String(func_name)).utf8();
- gdfunc->_func_cname = gdfunc->func_cname.get_data();
- }
+ codegen.generator->set_initial_line(p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line);
-#endif
- gdfunc->_initial_line = p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line;
#ifdef TOOLS_ENABLED
-
- p_script->member_lines[func_name] = gdfunc->_initial_line;
+ p_script->member_lines[func_name] = p_is_setter ? p_variable->setter->start_line : p_variable->getter->start_line;
#endif
-
- if (codegen.debug_stack) {
- gdfunc->stack_debug = codegen.stack_debug;
- }
+ memdelete(codegen.generator);
return OK;
}
@@ -2604,7 +1933,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->native = native;
} break;
case GDScriptDataType::GDSCRIPT: {
- Ref<GDScript> base = base_type.script_type;
+ Ref<GDScript> base = Ref<GDScript>(base_type.script_type);
p_script->base = base;
p_script->_base = base.ptr();
@@ -2671,7 +2000,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
break;
}
minfo.rpc_mode = variable->rpc_mode;
- minfo.data_type = _gdtype_from_datatype(variable->get_datatype());
+ minfo.data_type = _gdtype_from_datatype(variable->get_datatype(), p_script);
PropertyInfo prop_info = minfo.data_type;
prop_info.name = name;
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index e8601f69c7..db02079d26 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -33,109 +33,88 @@
#include "core/set.h"
#include "gdscript.h"
+#include "gdscript_codegen.h"
#include "gdscript_function.h"
#include "gdscript_parser.h"
class GDScriptCompiler {
- const GDScriptParser *parser;
+ const GDScriptParser *parser = nullptr;
Set<GDScript *> parsed_classes;
Set<GDScript *> parsing_classes;
- GDScript *main_script;
+ GDScript *main_script = nullptr;
+
struct CodeGen {
- GDScript *script;
- const GDScriptParser::ClassNode *class_node;
- const GDScriptParser::FunctionNode *function_node;
+ GDScript *script = nullptr;
+ const GDScriptParser::ClassNode *class_node = nullptr;
+ const GDScriptParser::FunctionNode *function_node = nullptr;
StringName function_name;
- bool debug_stack;
-
- List<Map<StringName, int>> stack_id_stack;
- Map<StringName, int> stack_identifiers;
-
- List<GDScriptFunction::StackDebug> stack_debug;
- List<Map<StringName, int>> block_identifier_stack;
- Map<StringName, int> block_identifiers;
- Map<StringName, int> local_named_constants;
-
- void add_stack_identifier(const StringName &p_id, int p_stackpos) {
- stack_identifiers[p_id] = p_stackpos;
- if (debug_stack) {
- block_identifiers[p_id] = p_stackpos;
- GDScriptFunction::StackDebug sd;
- sd.added = true;
- sd.line = current_line;
- sd.identifier = p_id;
- sd.pos = p_stackpos;
- stack_debug.push_back(sd);
- }
+ GDScriptCodeGenerator *generator = nullptr;
+ Map<StringName, GDScriptCodeGenerator::Address> parameters;
+ Map<StringName, GDScriptCodeGenerator::Address> locals;
+ List<Set<StringName>> locals_in_scope;
+
+ GDScriptCodeGenerator::Address add_local(const StringName &p_name, const GDScriptDataType &p_type) {
+ uint32_t addr = generator->add_local(p_name, p_type);
+ locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::LOCAL_VARIABLE, addr, p_type);
+ locals_in_scope.back()->get().insert(p_name);
+ return locals[p_name];
}
- void push_stack_identifiers() {
- stack_id_stack.push_back(stack_identifiers);
- if (debug_stack) {
- block_identifier_stack.push_back(block_identifiers);
- block_identifiers.clear();
- }
+ GDScriptCodeGenerator::Address add_local_constant(const StringName &p_name, const Variant &p_value) {
+ uint32_t addr = generator->add_local_constant(p_name, p_value);
+ locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::LOCAL_CONSTANT, addr);
+ return locals[p_name];
}
- void pop_stack_identifiers() {
- stack_identifiers = stack_id_stack.back()->get();
- stack_id_stack.pop_back();
-
- if (debug_stack) {
- for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) {
- GDScriptFunction::StackDebug sd;
- sd.added = false;
- sd.identifier = E->key();
- sd.line = current_line;
- sd.pos = E->get();
- stack_debug.push_back(sd);
- }
- block_identifiers = block_identifier_stack.back()->get();
- block_identifier_stack.pop_back();
- }
+ GDScriptCodeGenerator::Address add_temporary(const GDScriptDataType &p_type = GDScriptDataType()) {
+ uint32_t addr = generator->add_temporary();
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::TEMPORARY, addr, p_type);
}
- HashMap<Variant, int, VariantHasher, VariantComparator> constant_map;
- Map<StringName, int> name_map;
-#ifdef TOOLS_ENABLED
- Vector<StringName> named_globals;
-#endif
-
- int get_name_map_pos(const StringName &p_identifier) {
- int ret;
- if (!name_map.has(p_identifier)) {
- ret = name_map.size();
- name_map[p_identifier] = ret;
- } else {
- ret = name_map[p_identifier];
+ GDScriptCodeGenerator::Address add_constant(const Variant &p_constant) {
+ GDScriptDataType type;
+ type.has_type = true;
+ type.kind = GDScriptDataType::BUILTIN;
+ type.builtin_type = p_constant.get_type();
+ if (type.builtin_type == Variant::OBJECT) {
+ Object *obj = p_constant;
+ if (obj) {
+ type.kind = GDScriptDataType::NATIVE;
+ type.native_type = obj->get_class_name();
+
+ Ref<Script> script = obj->get_script();
+ if (script.is_valid()) {
+ type.script_type = script.ptr();
+ Ref<GDScript> gdscript = script;
+ if (gdscript.is_valid()) {
+ type.kind = GDScriptDataType::GDSCRIPT;
+ } else {
+ type.kind = GDScriptDataType::SCRIPT;
+ }
+ }
+ } else {
+ type.builtin_type = Variant::NIL;
+ }
}
- return ret;
- }
- int get_constant_pos(const Variant &p_constant) {
- if (constant_map.has(p_constant)) {
- return constant_map[p_constant] | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
- }
- int pos = constant_map.size();
- constant_map[p_constant] = pos;
- return pos | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
+ uint32_t addr = generator->add_or_get_constant(p_constant);
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CONSTANT, addr, type);
}
- Vector<int> opcodes;
- void alloc_stack(int p_level) {
- if (p_level >= stack_max) {
- stack_max = p_level + 1;
- }
+ void start_block() {
+ Set<StringName> scope;
+ locals_in_scope.push_back(scope);
+ generator->start_block();
}
- void alloc_call(int p_params) {
- if (p_params >= call_max) {
- call_max = p_params;
+
+ void end_block() {
+ Set<StringName> &scope = locals_in_scope.back()->get();
+ for (Set<StringName>::Element *E = scope.front(); E; E = E->next()) {
+ locals.erase(E->get());
}
+ locals_in_scope.pop_back();
+ generator->end_block();
}
-
- int current_line;
- int stack_max;
- int call_max;
};
bool _is_class_member_property(CodeGen &codegen, const StringName &p_name);
@@ -143,17 +122,16 @@ class GDScriptCompiler {
void _set_error(const String &p_error, const GDScriptParser::Node *p_node);
- bool _create_unary_operator(CodeGen &codegen, const GDScriptParser::UnaryOpNode *on, Variant::Operator op, int p_stack_level);
- bool _create_binary_operator(CodeGen &codegen, const GDScriptParser::BinaryOpNode *on, Variant::Operator op, int p_stack_level, bool p_initializer = false, int p_index_addr = 0);
- bool _create_binary_operator(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_left_operand, const GDScriptParser::ExpressionNode *p_right_operand, Variant::Operator op, int p_stack_level, bool p_initializer = false, int p_index_addr = 0);
- bool _generate_typed_assign(CodeGen &codegen, int p_src_address, int p_dst_address, const GDScriptDataType &p_datatype, const GDScriptParser::DataType &p_value_type);
+ Error _create_binary_operator(CodeGen &codegen, const GDScriptParser::BinaryOpNode *on, Variant::Operator op, bool p_initializer = false, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
+ Error _create_binary_operator(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_left_operand, const GDScriptParser::ExpressionNode *p_right_operand, Variant::Operator op, bool p_initializer = false, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
- GDScriptDataType _gdtype_from_datatype(const GDScriptParser::DataType &p_datatype) const;
+ GDScriptDataType _gdtype_from_datatype(const GDScriptParser::DataType &p_datatype, GDScript *p_owner = nullptr) const;
- int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::AssignmentNode *p_assignment, int p_stack_level, int p_index_addr = 0);
- int _parse_expression(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false, int p_index_addr = 0);
- Error _parse_match_pattern(CodeGen &codegen, const GDScriptParser::PatternNode *p_pattern, int p_stack_level, int p_value_addr, int p_type_addr, int &r_bound_variables, Vector<int> &r_patch_addresses, Vector<int> &r_block_patch_address);
- Error _parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1);
+ GDScriptCodeGenerator::Address _parse_assign_right_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::AssignmentNode *p_assignmentint, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
+ GDScriptCodeGenerator::Address _parse_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::ExpressionNode *p_expression, bool p_root = false, bool p_initializer = false, const GDScriptCodeGenerator::Address &p_index_addr = GDScriptCodeGenerator::Address());
+ GDScriptCodeGenerator::Address _parse_match_pattern(CodeGen &codegen, Error &r_error, const GDScriptParser::PatternNode *p_pattern, const GDScriptCodeGenerator::Address &p_value_addr, const GDScriptCodeGenerator::Address &p_type_addr, const GDScriptCodeGenerator::Address &p_previous_test, bool p_is_first, bool p_is_nested);
+ void _add_locals_in_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block);
+ Error _parse_block(CodeGen &codegen, const GDScriptParser::SuiteNode *p_block, bool p_add_locals = true);
Error _parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false);
Error _parse_setter_getter(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::VariableNode *p_variable, bool p_is_setter);
Error _parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index a4e37a79f8..e59f99fc56 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -34,6 +34,10 @@
#include "gdscript.h"
#include "gdscript_functions.h"
+#ifdef DEBUG_ENABLED
+#include "core/string_builder.h"
+#endif
+
Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const {
int address = p_address & ADDR_MASK;
@@ -105,9 +109,9 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
#ifdef TOOLS_ENABLED
case ADDR_TYPE_NAMED_GLOBAL: {
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _named_globals_count, nullptr);
+ ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
#endif
- StringName id = _named_globals_ptr[address];
+ StringName id = _global_names_ptr[address];
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(id)) {
return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
@@ -212,7 +216,6 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_CALL_RETURN, \
&&OPCODE_CALL_ASYNC, \
&&OPCODE_CALL_BUILT_IN, \
- &&OPCODE_CALL_SELF, \
&&OPCODE_CALL_SELF_BASE, \
&&OPCODE_AWAIT, \
&&OPCODE_AWAIT_RESUME, \
@@ -1055,7 +1058,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
err_text = "Got a freed object as a result of the call.";
OPCODE_BREAK;
}
- if (obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {
+ if (obj && obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {
err_text = R"(Trying to call an async function without "await".)";
OPCODE_BREAK;
}
@@ -1139,10 +1142,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
- OPCODE(OPCODE_CALL_SELF) {
- OPCODE_BREAK;
- }
-
OPCODE(OPCODE_CALL_SELF_BASE) {
CHECK_SPACE(2);
int self_fun = _code_ptr[ip + 1];
@@ -1214,8 +1213,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_AWAIT) {
- int ipofs = 2;
- CHECK_SPACE(3);
+ CHECK_SPACE(2);
//do the oneshot connect
GET_VARIANT_PTR(argobj, 1);
@@ -1265,7 +1263,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
gdfs->state.stack_size = _stack_size;
gdfs->state.self = self;
gdfs->state.alloca_size = alloca_size;
- gdfs->state.ip = ip + ipofs;
+ gdfs->state.ip = ip + 2;
gdfs->state.line = line;
gdfs->state.script = _script;
{
@@ -1884,3 +1882,506 @@ GDScriptFunctionState::~GDScriptFunctionState() {
instances_list.remove_from_list();
}
}
+
+#ifdef DEBUG_ENABLED
+static String _get_variant_string(const Variant &p_variant) {
+ String txt;
+ if (p_variant.get_type() == Variant::STRING) {
+ txt = "\"" + String(p_variant) + "\"";
+ } else if (p_variant.get_type() == Variant::STRING_NAME) {
+ txt = "&\"" + String(p_variant) + "\"";
+ } else if (p_variant.get_type() == Variant::NODE_PATH) {
+ txt = "^\"" + String(p_variant) + "\"";
+ } else if (p_variant.get_type() == Variant::OBJECT) {
+ Object *obj = p_variant;
+ if (!obj) {
+ txt = "null";
+ } else {
+ GDScriptNativeClass *cls = Object::cast_to<GDScriptNativeClass>(obj);
+ if (cls) {
+ txt += cls->get_name();
+ txt += " (class)";
+ } else {
+ txt = obj->get_class();
+ if (obj->get_script_instance()) {
+ txt += "(" + obj->get_script_instance()->get_script()->get_path() + ")";
+ }
+ }
+ }
+ } else {
+ txt = p_variant;
+ }
+ return txt;
+}
+
+static String _disassemble_address(const GDScript *p_script, const GDScriptFunction &p_function, int p_address) {
+ int addr = p_address & GDScriptFunction::ADDR_MASK;
+
+ switch (p_address >> GDScriptFunction::ADDR_BITS) {
+ case GDScriptFunction::ADDR_TYPE_SELF: {
+ return "self";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_CLASS: {
+ return "class";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_MEMBER: {
+ return "member(" + p_script->debug_get_member_by_index(addr) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT: {
+ return "class_const(" + p_function.get_global_name(addr) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT: {
+ return "const(" + _get_variant_string(p_function.get_constant(addr)) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_STACK: {
+ return "stack(" + itos(addr) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_STACK_VARIABLE: {
+ return "var_stack(" + itos(addr) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_GLOBAL: {
+ return "global(" + _get_variant_string(GDScriptLanguage::get_singleton()->get_global_array()[addr]) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL: {
+ return "named_global(" + p_function.get_global_name(addr) + ")";
+ } break;
+ case GDScriptFunction::ADDR_TYPE_NIL: {
+ return "nil";
+ } break;
+ }
+
+ return "<err>";
+}
+
+void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
+#define DADDR(m_ip) (_disassemble_address(_script, *this, _code_ptr[ip + m_ip]))
+
+ for (int ip = 0; ip < _code_size;) {
+ StringBuilder text;
+ int incr = 0;
+
+ text += " ";
+ text += itos(ip);
+ text += ": ";
+
+ // This makes the compiler complain if some opcode is unchecked in the switch.
+ Opcode code = Opcode(_code_ptr[ip]);
+
+ switch (code) {
+ case OPCODE_OPERATOR: {
+ int operation = _code_ptr[ip + 1];
+
+ text += "operator ";
+
+ text += DADDR(4);
+ text += " = ";
+ text += DADDR(2);
+ text += " ";
+ text += Variant::get_operator_name(Variant::Operator(operation));
+ text += " ";
+ text += DADDR(3);
+
+ incr += 5;
+ } break;
+ case OPCODE_EXTENDS_TEST: {
+ text += "is object ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(1);
+ text += " is ";
+ text += DADDR(2);
+
+ incr += 4;
+ } break;
+ case OPCODE_IS_BUILTIN: {
+ text += "is builtin ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(1);
+ text += " is ";
+ text += Variant::get_type_name(Variant::Type(_code_ptr[ip + 2]));
+
+ incr += 4;
+ } break;
+ case OPCODE_SET: {
+ text += "set ";
+ text += DADDR(1);
+ text += "[";
+ text += DADDR(2);
+ text += "] = ";
+ text += DADDR(3);
+
+ incr += 4;
+ } break;
+ case OPCODE_GET: {
+ text += "get ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(1);
+ text += "[";
+ text += DADDR(2);
+ text += "]";
+
+ incr += 4;
+ } break;
+ case OPCODE_SET_NAMED: {
+ text += "set_named ";
+ text += DADDR(1);
+ text += "[\"";
+ text += _global_names_ptr[_code_ptr[ip + 2]];
+ text += "\"] = ";
+ text += DADDR(3);
+
+ incr += 4;
+ } break;
+ case OPCODE_GET_NAMED: {
+ text += "get_named ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(1);
+ text += "[\"";
+ text += _global_names_ptr[_code_ptr[ip + 2]];
+ text += "\"]";
+
+ incr += 4;
+ } break;
+ case OPCODE_SET_MEMBER: {
+ text += "set_member ";
+ text += "[\"";
+ text += _global_names_ptr[_code_ptr[ip + 1]];
+ text += "\"] = ";
+ text += DADDR(2);
+
+ incr += 3;
+ } break;
+ case OPCODE_GET_MEMBER: {
+ text += "get_member ";
+ text += DADDR(2);
+ text += " = ";
+ text += "[\"";
+ text += _global_names_ptr[_code_ptr[ip + 1]];
+ text += "\"]";
+
+ incr += 3;
+ } break;
+ case OPCODE_ASSIGN: {
+ text += "assign ";
+ text += DADDR(1);
+ text += " = ";
+ text += DADDR(2);
+
+ incr += 3;
+ } break;
+ case OPCODE_ASSIGN_TRUE: {
+ text += "assign ";
+ text += DADDR(1);
+ text += " = true";
+
+ incr += 2;
+ } break;
+ case OPCODE_ASSIGN_FALSE: {
+ text += "assign ";
+ text += DADDR(1);
+ text += " = false";
+
+ incr += 2;
+ } break;
+ case OPCODE_ASSIGN_TYPED_BUILTIN: {
+ text += "assign typed builtin (";
+ text += Variant::get_type_name((Variant::Type)_code_ptr[ip + 1]);
+ text += ") ";
+ text += DADDR(2);
+ text += " = ";
+ text += DADDR(3);
+
+ incr += 4;
+ } break;
+ case OPCODE_ASSIGN_TYPED_NATIVE: {
+ Variant class_name = _constants_ptr[_code_ptr[ip + 1]];
+ GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(class_name.operator Object *());
+
+ text += "assign typed native (";
+ text += nc->get_name().operator String();
+ text += ") ";
+ text += DADDR(2);
+ text += " = ";
+ text += DADDR(3);
+
+ incr += 4;
+ } break;
+ case OPCODE_ASSIGN_TYPED_SCRIPT: {
+ Variant script = _constants_ptr[_code_ptr[ip + 1]];
+ Script *sc = Object::cast_to<Script>(script.operator Object *());
+
+ text += "assign typed script (";
+ text += sc->get_path();
+ text += ") ";
+ text += DADDR(2);
+ text += " = ";
+ text += DADDR(3);
+
+ incr += 4;
+ } break;
+ case OPCODE_CAST_TO_BUILTIN: {
+ text += "cast builtin ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(2);
+ text += " as ";
+ text += Variant::get_type_name(Variant::Type(_code_ptr[ip + 1]));
+
+ incr += 4;
+ } break;
+ case OPCODE_CAST_TO_NATIVE: {
+ Variant class_name = _constants_ptr[_code_ptr[ip + 1]];
+ GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(class_name.operator Object *());
+
+ text += "cast native ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(2);
+ text += " as ";
+ text += nc->get_name();
+
+ incr += 4;
+ } break;
+ case OPCODE_CAST_TO_SCRIPT: {
+ text += "cast ";
+ text += DADDR(3);
+ text += " = ";
+ text += DADDR(2);
+ text += " as ";
+ text += DADDR(1);
+
+ incr += 4;
+ } break;
+ case OPCODE_CONSTRUCT: {
+ Variant::Type t = Variant::Type(_code_ptr[ip + 1]);
+ int argc = _code_ptr[ip + 2];
+
+ text += "construct ";
+ text += DADDR(3 + argc);
+ text += " = ";
+
+ text += Variant::get_type_name(t) + "(";
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(i + 3);
+ }
+ text += ")";
+
+ incr = 4 + argc;
+ } break;
+ case OPCODE_CONSTRUCT_ARRAY: {
+ int argc = _code_ptr[ip + 1];
+ text += " make_array ";
+ text += DADDR(2 + argc);
+ text += " = [";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(2 + i);
+ }
+
+ text += "]";
+
+ incr += 3 + argc;
+ } break;
+ case OPCODE_CONSTRUCT_DICTIONARY: {
+ int argc = _code_ptr[ip + 1];
+ text += "make_dict ";
+ text += DADDR(2 + argc * 2);
+ text += " = {";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(2 + i * 2 + 0);
+ text += ": ";
+ text += DADDR(2 + i * 2 + 1);
+ }
+
+ text += "}";
+
+ incr += 3 + argc * 2;
+ } break;
+ case OPCODE_CALL:
+ case OPCODE_CALL_RETURN:
+ case OPCODE_CALL_ASYNC: {
+ bool ret = _code_ptr[ip] == OPCODE_CALL_RETURN;
+ bool async = _code_ptr[ip] == OPCODE_CALL_ASYNC;
+
+ if (ret) {
+ text += "call-ret ";
+ } else if (async) {
+ text += "call-async ";
+ } else {
+ text += "call ";
+ }
+
+ int argc = _code_ptr[ip + 1];
+ if (ret || async) {
+ text += DADDR(4 + argc) + " = ";
+ }
+
+ text += DADDR(2) + ".";
+ text += String(_global_names_ptr[_code_ptr[ip + 3]]);
+ text += "(";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(4 + i);
+ }
+ text += ")";
+
+ incr = 5 + argc;
+ } break;
+ case OPCODE_CALL_BUILT_IN: {
+ text += "call-built-in ";
+
+ int argc = _code_ptr[ip + 2];
+ text += DADDR(3 + argc) + " = ";
+
+ text += GDScriptFunctions::get_func_name(GDScriptFunctions::Function(_code_ptr[ip + 1]));
+ text += "(";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(3 + i);
+ }
+ text += ")";
+
+ incr = 4 + argc;
+ } break;
+ case OPCODE_CALL_SELF_BASE: {
+ text += "call-self-base ";
+
+ int argc = _code_ptr[ip + 2];
+ text += DADDR(3 + argc) + " = ";
+
+ text += _global_names_ptr[_code_ptr[ip + 1]];
+ text += "(";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0)
+ text += ", ";
+ text += DADDR(3 + i);
+ }
+ text += ")";
+
+ incr = 4 + argc;
+ } break;
+ case OPCODE_AWAIT: {
+ text += "await ";
+ text += DADDR(1);
+
+ incr += 2;
+ } break;
+ case OPCODE_AWAIT_RESUME: {
+ text += "await resume ";
+ text += DADDR(1);
+
+ incr = 2;
+ } break;
+ case OPCODE_JUMP: {
+ text += "jump ";
+ text += itos(_code_ptr[ip + 1]);
+
+ incr = 2;
+ } break;
+ case OPCODE_JUMP_IF: {
+ text += "jump-if ";
+ text += DADDR(1);
+ text += " to ";
+ text += itos(_code_ptr[ip + 2]);
+
+ incr = 3;
+ } break;
+ case OPCODE_JUMP_IF_NOT: {
+ text += "jump-if-not ";
+ text += DADDR(1);
+ text += " to ";
+ text += itos(_code_ptr[ip + 2]);
+
+ incr = 3;
+ } break;
+ case OPCODE_JUMP_TO_DEF_ARGUMENT: {
+ text += "jump-to-default-argument ";
+
+ incr = 1;
+ } break;
+ case OPCODE_RETURN: {
+ text += "return ";
+ text += DADDR(1);
+
+ incr = 2;
+ } break;
+ case OPCODE_ITERATE_BEGIN: {
+ text += "for-init ";
+ text += DADDR(4);
+ text += " in ";
+ text += DADDR(2);
+ text += " counter ";
+ text += DADDR(1);
+ text += " end ";
+ text += itos(_code_ptr[ip + 3]);
+
+ incr += 5;
+ } break;
+ case OPCODE_ITERATE: {
+ text += "for-loop ";
+ text += DADDR(4);
+ text += " in ";
+ text += DADDR(2);
+ text += " counter ";
+ text += DADDR(1);
+ text += " end ";
+ text += itos(_code_ptr[ip + 3]);
+
+ incr += 5;
+ } break;
+ case OPCODE_LINE: {
+ int line = _code_ptr[ip + 1] - 1;
+ if (line >= 0 && line < p_code_lines.size()) {
+ text += "line ";
+ text += itos(line + 1);
+ text += ": ";
+ text += p_code_lines[line];
+ } else {
+ text += "";
+ }
+
+ incr += 2;
+ } break;
+ case OPCODE_ASSERT: {
+ text += "assert (";
+ text += DADDR(1);
+ text += ", ";
+ text += DADDR(2);
+ text += ")";
+
+ incr += 3;
+ } break;
+ case OPCODE_BREAKPOINT: {
+ text += "breakpoint";
+
+ incr += 1;
+ } break;
+ case OPCODE_END: {
+ text += "== END ==";
+
+ incr += 1;
+ } break;
+ }
+
+ ip += incr;
+ if (text.get_string_length() > 0) {
+ print_line(text.as_string());
+ }
+ }
+}
+#endif
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 771baf6a08..c98ac09310 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -56,7 +56,8 @@ struct GDScriptDataType {
bool has_type = false;
Variant::Type builtin_type = Variant::NIL;
StringName native_type;
- Ref<Script> script_type;
+ Script *script_type = nullptr;
+ Ref<Script> script_type_ref;
bool is_type(const Variant &p_variant, bool p_allow_implicit_conversion = false) const {
if (!has_type) {
@@ -182,7 +183,6 @@ public:
OPCODE_CALL_RETURN,
OPCODE_CALL_ASYNC,
OPCODE_CALL_BUILT_IN,
- OPCODE_CALL_SELF,
OPCODE_CALL_SELF_BASE,
OPCODE_AWAIT,
OPCODE_AWAIT_RESUME,
@@ -224,6 +224,7 @@ public:
private:
friend class GDScriptCompiler;
+ friend class GDScriptByteCodeGenerator;
StringName source;
@@ -232,10 +233,6 @@ private:
int _constant_count;
const StringName *_global_names_ptr;
int _global_names_count;
-#ifdef TOOLS_ENABLED
- const StringName *_named_globals_ptr;
- int _named_globals_count;
-#endif
const int *_default_arg_ptr;
int _default_arg_count;
const int *_code_ptr;
@@ -252,9 +249,6 @@ private:
StringName name;
Vector<Variant> constants;
Vector<StringName> global_names;
-#ifdef TOOLS_ENABLED
- Vector<StringName> named_globals;
-#endif
Vector<int> default_arguments;
Vector<int> code;
Vector<GDScriptDataType> argument_types;
@@ -344,6 +338,10 @@ public:
Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state = nullptr);
+#ifdef DEBUG_ENABLED
+ void disassemble(const Vector<String> &p_code_lines) const;
+#endif
+
_FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; }
GDScriptFunction();
~GDScriptFunction();
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index fefbf906f0..31ce63bc6e 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -635,7 +635,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case TEXT_CHAR: {
VALIDATE_ARG_COUNT(1);
VALIDATE_ARG_NUM(0);
- CharType result[2] = { *p_args[0], 0 };
+ char32_t result[2] = { *p_args[0], 0 };
r_ret = String(result);
} break;
case TEXT_ORD: {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 03da5e926b..2a69db130b 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -327,7 +327,7 @@ Error GDScriptParser::parse(const String &p_source_code, const String &p_script_
bool found = false;
const String &line = lines[i];
for (int j = 0; j < line.size(); j++) {
- if (line[j] == CharType(0xFFFF)) {
+ if (line[j] == char32_t(0xFFFF)) {
found = true;
break;
} else if (line[j] == '\t') {
@@ -586,6 +586,14 @@ GDScriptParser::ClassNode *GDScriptParser::parse_class() {
return n_class;
}
+ if (match(GDScriptTokenizer::Token::EXTENDS)) {
+ if (n_class->extends_used) {
+ push_error(R"(Cannot use "extends" more than once in the same class.)");
+ }
+ parse_extends();
+ end_statement("superclass");
+ }
+
parse_class_body();
consume(GDScriptTokenizer::Token::DEDENT, R"(Missing unindent at the end of the class body.)");
@@ -1034,7 +1042,7 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() {
if (check(GDScriptTokenizer::Token::BRACE_CLOSE)) {
break; // Allow trailing comma.
}
- if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifer for enum key.)")) {
+ if (consume(GDScriptTokenizer::Token::IDENTIFIER, R"(Expected identifier for enum key.)")) {
EnumNode::Value item;
item.identifier = parse_identifier();
item.parent_enum = enum_node;
@@ -1468,7 +1476,9 @@ GDScriptParser::ContinueNode *GDScriptParser::parse_continue() {
}
current_suite->has_continue = true;
end_statement(R"("continue")");
- return alloc_node<ContinueNode>();
+ ContinueNode *cont = alloc_node<ContinueNode>();
+ cont->is_for_match = is_continue_match;
+ return cont;
}
GDScriptParser::ForNode *GDScriptParser::parse_for() {
@@ -1487,10 +1497,12 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Save break/continue state.
bool could_break = can_break;
bool could_continue = can_continue;
+ bool was_continue_match = is_continue_match;
// Allow break/continue.
can_break = true;
can_continue = true;
+ is_continue_match = false;
SuiteNode *suite = alloc_node<SuiteNode>();
if (n_for->variable) {
@@ -1503,6 +1515,7 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
// Reset break/continue state.
can_break = could_break;
can_continue = could_continue;
+ is_continue_match = was_continue_match;
return n_for;
}
@@ -1637,8 +1650,10 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
// Save continue state.
bool could_continue = can_continue;
+ bool was_continue_match = is_continue_match;
// Allow continue for match.
can_continue = true;
+ is_continue_match = true;
SuiteNode *suite = alloc_node<SuiteNode>();
if (branch->patterns.size() > 0) {
@@ -1655,6 +1670,7 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
// Restore continue state.
can_continue = could_continue;
+ is_continue_match = was_continue_match;
return branch;
}
@@ -1812,16 +1828,19 @@ GDScriptParser::WhileNode *GDScriptParser::parse_while() {
// Save break/continue state.
bool could_break = can_break;
bool could_continue = can_continue;
+ bool was_continue_match = is_continue_match;
// Allow break/continue.
can_break = true;
can_continue = true;
+ is_continue_match = false;
n_while->loop = parse_suite(R"("while" block)");
// Reset break/continue state.
can_break = could_break;
can_continue = could_continue;
+ is_continue_match = was_continue_match;
return n_while;
}
@@ -1941,8 +1960,8 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_literal(ExpressionNode *p_
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_self(ExpressionNode *p_previous_operand, bool p_can_assign) {
- if (!current_function || current_function->is_static) {
- push_error(R"(Cannot use "self" outside a non-static function.)");
+ if (current_function && current_function->is_static) {
+ push_error(R"(Cannot use "self" inside a static function.)");
}
SelfNode *self = alloc_node<SelfNode>();
self->current_class = current_class;
@@ -2497,7 +2516,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre
GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p_previous_operand, bool p_can_assign) {
if (match(GDScriptTokenizer::Token::LITERAL)) {
if (previous.literal.get_type() != Variant::STRING) {
- push_error(R"(Expect node path as string or identifer after "$".)");
+ push_error(R"(Expect node path as string or identifier after "$".)");
return nullptr;
}
GetNodeNode *get_node = alloc_node<GetNodeNode>();
@@ -2520,7 +2539,7 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_get_node(ExpressionNode *p
} while (match(GDScriptTokenizer::Token::SLASH));
return get_node;
} else {
- push_error(R"(Expect node path as string or identifer after "$".)");
+ push_error(R"(Expect node path as string or identifier after "$".)");
return nullptr;
}
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 7d8ae7fc55..4c9473c7bd 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -609,6 +609,7 @@ public:
};
struct ContinueNode : public Node {
+ bool is_for_match = false;
ContinueNode() {
type = CONTINUE;
}
@@ -1079,6 +1080,7 @@ private:
bool panic_mode = false;
bool can_break = false;
bool can_continue = false;
+ bool is_continue_match = false; // Whether a `continue` will act on a `match`.
bool is_ignoring_warnings = false;
List<bool> multiline_stack;
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 737e920693..9a40aa50ac 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -222,7 +222,7 @@ String GDScriptTokenizer::get_token_name(Token::Type p_token_type) {
void GDScriptTokenizer::set_source_code(const String &p_source_code) {
source = p_source_code;
if (source.empty()) {
- _source = L"";
+ _source = U"";
} else {
_source = source.ptr();
}
@@ -263,7 +263,7 @@ bool GDScriptTokenizer::is_past_cursor() const {
return true;
}
-CharType GDScriptTokenizer::_advance() {
+char32_t GDScriptTokenizer::_advance() {
if (unlikely(_is_at_end())) {
return '\0';
}
@@ -282,15 +282,15 @@ CharType GDScriptTokenizer::_advance() {
return _peek(-1);
}
-void GDScriptTokenizer::push_paren(CharType p_char) {
+void GDScriptTokenizer::push_paren(char32_t p_char) {
paren_stack.push_back(p_char);
}
-bool GDScriptTokenizer::pop_paren(CharType p_expected) {
+bool GDScriptTokenizer::pop_paren(char32_t p_expected) {
if (paren_stack.empty()) {
return false;
}
- CharType actual = paren_stack.back()->get();
+ char32_t actual = paren_stack.back()->get();
paren_stack.pop_back();
return actual == p_expected;
@@ -302,19 +302,19 @@ GDScriptTokenizer::Token GDScriptTokenizer::pop_error() {
return error;
}
-static bool _is_alphanumeric(CharType c) {
+static bool _is_alphanumeric(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-static bool _is_digit(CharType c) {
+static bool _is_digit(char32_t c) {
return (c >= '0' && c <= '9');
}
-static bool _is_hex_digit(CharType c) {
+static bool _is_hex_digit(char32_t c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
-static bool _is_binary_digit(CharType c) {
+static bool _is_binary_digit(char32_t c) {
return (c == '0' || c == '1');
}
@@ -404,7 +404,7 @@ void GDScriptTokenizer::push_error(const Token &p_error) {
error_stack.push_back(p_error);
}
-GDScriptTokenizer::Token GDScriptTokenizer::make_paren_error(CharType p_paren) {
+GDScriptTokenizer::Token GDScriptTokenizer::make_paren_error(char32_t p_paren) {
if (paren_stack.empty()) {
return make_error(vformat("Closing \"%c\" doesn't have an opening counterpart.", p_paren));
}
@@ -413,8 +413,8 @@ GDScriptTokenizer::Token GDScriptTokenizer::make_paren_error(CharType p_paren) {
return error;
}
-GDScriptTokenizer::Token GDScriptTokenizer::check_vcs_marker(CharType p_test, Token::Type p_double_type) {
- const CharType *next = _current + 1;
+GDScriptTokenizer::Token GDScriptTokenizer::check_vcs_marker(char32_t p_test, Token::Type p_double_type) {
+ const char32_t *next = _current + 1;
int chars = 2; // Two already matched.
// Test before consuming characters, since we don't want to consume more than needed.
@@ -578,7 +578,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::potential_identifier() {
}
void GDScriptTokenizer::newline(bool p_make_token) {
- // Don't overwrite previous newline, nor create if we want a line contination.
+ // Don't overwrite previous newline, nor create if we want a line continuation.
if (p_make_token && !pending_newline && !line_continuation) {
Token newline(Token::NEWLINE);
newline.start_line = line;
@@ -602,7 +602,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
bool has_decimal = false;
bool has_exponent = false;
bool has_error = false;
- bool (*digit_check_func)(CharType) = _is_digit;
+ bool (*digit_check_func)(char32_t) = _is_digit;
if (_peek(-1) == '.') {
has_decimal = true;
@@ -621,7 +621,19 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
}
// Allow '_' to be used in a number, for readability.
+ bool previous_was_underscore = false;
while (digit_check_func(_peek()) || _peek() == '_') {
+ if (_peek() == '_') {
+ if (previous_was_underscore) {
+ Token error = make_error(R"(Only one underscore can be used as a numeric separator.)");
+ error.start_column = column;
+ error.leftmost_column = column;
+ error.end_column = column + 1;
+ error.rightmost_column = column + 1;
+ push_error(error);
+ }
+ previous_was_underscore = true;
+ }
_advance();
}
@@ -672,7 +684,27 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
_advance();
}
// Consume exponent digits.
+ if (!_is_digit(_peek())) {
+ Token error = make_error(R"(Expected exponent value after "e".)");
+ error.start_column = column;
+ error.leftmost_column = column;
+ error.end_column = column + 1;
+ error.rightmost_column = column + 1;
+ push_error(error);
+ }
+ previous_was_underscore = false;
while (_is_digit(_peek()) || _peek() == '_') {
+ if (_peek() == '_') {
+ if (previous_was_underscore) {
+ Token error = make_error(R"(Only one underscore can be used as a numeric separator.)");
+ error.start_column = column;
+ error.leftmost_column = column;
+ error.end_column = column + 1;
+ error.rightmost_column = column + 1;
+ push_error(error);
+ }
+ previous_was_underscore = true;
+ }
_advance();
}
}
@@ -730,7 +762,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
_advance();
}
- CharType quote_char = _peek(-1);
+ char32_t quote_char = _peek(-1);
if (_peek() == quote_char && _peek(1) == quote_char) {
is_multiline = true;
@@ -747,7 +779,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
return make_error("Unterminated string.");
}
- CharType ch = _peek();
+ char32_t ch = _peek();
if (ch == '\\') {
// Escape pattern.
@@ -757,13 +789,13 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
}
// Grab escape character.
- CharType code = _peek();
+ char32_t code = _peek();
_advance();
if (_is_at_end()) {
return make_error("Unterminated string.");
}
- CharType escaped = 0;
+ char32_t escaped = 0;
bool valid_escape = true;
switch (code) {
@@ -804,8 +836,8 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
return make_error("Unterminated string.");
}
- CharType digit = _peek();
- CharType value = 0;
+ char32_t digit = _peek();
+ char32_t value = 0;
if (digit >= '0' && digit <= '9') {
value = digit - '0';
} else if (digit >= 'a' && digit <= 'f') {
@@ -908,7 +940,7 @@ void GDScriptTokenizer::check_indent() {
}
for (;;) {
- CharType current_indent_char = _peek();
+ char32_t current_indent_char = _peek();
int indent_count = 0;
if (current_indent_char != ' ' && current_indent_char != '\t' && current_indent_char != '\r' && current_indent_char != '\n' && current_indent_char != '#') {
@@ -938,7 +970,7 @@ void GDScriptTokenizer::check_indent() {
// Check indent level.
bool mixed = false;
while (!_is_at_end()) {
- CharType space = _peek();
+ char32_t space = _peek();
if (space == '\t') {
// Consider individual tab columns.
column += tab_size - 1;
@@ -1007,7 +1039,7 @@ void GDScriptTokenizer::check_indent() {
// First time indenting, choose character now.
indent_char = current_indent_char;
} else if (current_indent_char != indent_char) {
- Token error = make_error(vformat("Used \"%c\" for indentation instead \"%c\" as used before in the file.", String(&current_indent_char, 1).c_escape(), String(&indent_char, 1).c_escape()));
+ Token error = make_error(vformat("Used \"%s\" for indentation instead \"%s\" as used before in the file.", String(&current_indent_char, 1).c_escape(), String(&indent_char, 1).c_escape()));
error.start_line = line;
error.start_column = 1;
error.leftmost_column = 1;
@@ -1071,7 +1103,7 @@ void GDScriptTokenizer::_skip_whitespace() {
}
for (;;) {
- CharType c = _peek();
+ char32_t c = _peek();
switch (c) {
case ' ':
_advance();
@@ -1160,7 +1192,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() {
return make_token(Token::TK_EOF);
}
- const CharType c = _advance();
+ const char32_t c = _advance();
if (c == '\\') {
// Line continuation with backslash.
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 100ed3f132..4453982d08 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -183,14 +183,14 @@ public:
private:
String source;
- const CharType *_source = nullptr;
- const CharType *_current = nullptr;
+ const char32_t *_source = nullptr;
+ const char32_t *_current = nullptr;
int line = -1, column = -1;
int cursor_line = -1, cursor_column = -1;
int tab_size = 4;
// Keep track of multichar tokens.
- const CharType *_start = nullptr;
+ const char32_t *_start = nullptr;
int start_line = 0, start_column = 0;
int leftmost_column = 0, rightmost_column = 0;
@@ -202,30 +202,30 @@ private:
Token last_newline;
int pending_indents = 0;
List<int> indent_stack;
- List<CharType> paren_stack;
- CharType indent_char = '\0';
+ List<char32_t> paren_stack;
+ char32_t indent_char = '\0';
int position = 0;
int length = 0;
_FORCE_INLINE_ bool _is_at_end() { return position >= length; }
- _FORCE_INLINE_ CharType _peek(int p_offset = 0) { return position + p_offset >= 0 && position + p_offset < length ? _current[p_offset] : '\0'; }
+ _FORCE_INLINE_ char32_t _peek(int p_offset = 0) { return position + p_offset >= 0 && position + p_offset < length ? _current[p_offset] : '\0'; }
int indent_level() const { return indent_stack.size(); }
bool has_error() const { return !error_stack.empty(); }
Token pop_error();
- CharType _advance();
+ char32_t _advance();
void _skip_whitespace();
void check_indent();
Token make_error(const String &p_message);
void push_error(const String &p_message);
void push_error(const Token &p_error);
- Token make_paren_error(CharType p_paren);
+ Token make_paren_error(char32_t p_paren);
Token make_token(Token::Type p_type);
Token make_literal(const Variant &p_literal);
Token make_identifier(const StringName &p_identifier);
- Token check_vcs_marker(CharType p_test, Token::Type p_double_type);
- void push_paren(CharType p_char);
- bool pop_paren(CharType p_expected);
+ Token check_vcs_marker(char32_t p_test, Token::Type p_double_type);
+ void push_paren(char32_t p_char);
+ bool pop_paren(char32_t p_expected);
void newline(bool p_make_token);
Token number();
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 4d79d9d395..668dfd4835 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -491,7 +491,7 @@ String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &
int start_pos = p_position.character;
for (int c = p_position.character; c >= 0; c--) {
start_pos = c;
- CharType ch = line[c];
+ char32_t ch = line[c];
bool valid_char = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
if (!valid_char) {
break;
@@ -500,7 +500,7 @@ String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &
int end_pos = p_position.character;
for (int c = p_position.character; c < line.length(); c++) {
- CharType ch = line[c];
+ char32_t ch = line[c];
bool valid_char = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
if (!valid_char) {
break;
@@ -552,7 +552,7 @@ Error ExtendGDScriptParser::get_left_function_call(const lsp::Position &p_positi
}
while (c >= 0) {
- const CharType &character = line[c];
+ const char32_t &character = line[c];
if (character == ')') {
++bracket_stack;
} else if (character == '(') {
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index c554cbac05..da4cbe34c7 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -39,6 +39,11 @@
#include "gdscript_cache.h"
#include "gdscript_tokenizer.h"
+#ifdef TESTS_ENABLED
+#include "tests/test_gdscript.h"
+#include "tests/test_macros.h"
+#endif
+
GDScriptLanguage *script_language_gd = nullptr;
Ref<ResourceFormatLoaderGDScript> resource_loader_gd;
Ref<ResourceFormatSaverGDScript> resource_saver_gd;
@@ -79,7 +84,7 @@ public:
return;
}
- // TODO: Readd compiled/encrypted GDScript on export.
+ // TODO: Readd compiled GDScript on export.
return;
}
};
@@ -153,3 +158,26 @@ void unregister_gdscript_types() {
GDScriptParser::cleanup();
GDScriptAnalyzer::cleanup();
}
+
+#ifdef TESTS_ENABLED
+void test_tokenizer() {
+ TestGDScript::test(TestGDScript::TestType::TEST_TOKENIZER);
+}
+
+void test_parser() {
+ TestGDScript::test(TestGDScript::TestType::TEST_PARSER);
+}
+
+void test_compiler() {
+ TestGDScript::test(TestGDScript::TestType::TEST_COMPILER);
+}
+
+void test_bytecode() {
+ TestGDScript::test(TestGDScript::TestType::TEST_BYTECODE);
+}
+
+REGISTER_TEST_COMMAND("gdscript-tokenizer", &test_tokenizer);
+REGISTER_TEST_COMMAND("gdscript-parser", &test_parser);
+REGISTER_TEST_COMMAND("gdscript-compiler", &test_compiler);
+REGISTER_TEST_COMMAND("gdscript-bytecode", &test_bytecode);
+#endif
diff --git a/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp
index a50311972f..68d9984b43 100644
--- a/tests/test_gdscript.cpp
+++ b/modules/gdscript/tests/test_gdscript.cpp
@@ -35,9 +35,8 @@
#include "core/os/os.h"
#include "core/string_builder.h"
-#include "modules/modules_enabled.gen.h"
-#ifdef MODULE_GDSCRIPT_ENABLED
-
+#include "modules/gdscript/gdscript_analyzer.h"
+#include "modules/gdscript/gdscript_compiler.h"
#include "modules/gdscript/gdscript_parser.h"
#include "modules/gdscript/gdscript_tokenizer.h"
@@ -122,21 +121,79 @@ static void test_parser(const String &p_code, const String &p_script_path, const
printer.print_tree(parser);
}
-MainLoop *test(TestType p_type) {
+static void test_compiler(const String &p_code, const String &p_script_path, const Vector<String> &p_lines) {
+ GDScriptParser parser;
+ Error err = parser.parse(p_code, p_script_path, false);
+
+ if (err != OK) {
+ print_line("Error in parser:");
+ const List<GDScriptParser::ParserError> &errors = parser.get_errors();
+ for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
+ const GDScriptParser::ParserError &error = E->get();
+ print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
+ }
+ return;
+ }
+
+ GDScriptAnalyzer analyzer(&parser);
+ err = analyzer.analyze();
+
+ if (err != OK) {
+ print_line("Error in analyzer:");
+ const List<GDScriptParser::ParserError> &errors = parser.get_errors();
+ for (const List<GDScriptParser::ParserError>::Element *E = errors.front(); E != nullptr; E = E->next()) {
+ const GDScriptParser::ParserError &error = E->get();
+ print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
+ }
+ return;
+ }
+
+ GDScriptCompiler compiler;
+ Ref<GDScript> script;
+ script.instance();
+ script->set_path(p_script_path);
+
+ err = compiler.compile(&parser, script.ptr(), false);
+
+ if (err) {
+ print_line("Error in compiler:");
+ print_line(vformat("%02d:%02d: %s", compiler.get_error_line(), compiler.get_error_column(), compiler.get_error()));
+ return;
+ }
+
+ for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) {
+ const GDScriptFunction *func = E->value();
+
+ String signature = "Disassembling " + func->get_name().operator String() + "(";
+ for (int i = 0; i < func->get_argument_count(); i++) {
+ if (i > 0) {
+ signature += ", ";
+ }
+ signature += func->get_argument_name(i);
+ }
+ print_line(signature + ")");
+
+ func->disassemble(p_lines);
+ print_line("");
+ print_line("");
+ }
+}
+
+void test(TestType p_type) {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
if (cmdlargs.empty()) {
- return nullptr;
+ return;
}
String test = cmdlargs.back()->get();
if (!test.ends_with(".gd")) {
print_line("This test expects a path to a GDScript file as its last parameter. Got: " + test);
- return nullptr;
+ return;
}
FileAccessRef fa = FileAccess::open(test, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!fa, nullptr, "Could not open file: " + test);
+ ERR_FAIL_COND_MSG(!fa, "Could not open file: " + test);
Vector<uint8_t> buf;
int flen = fa->get_len();
@@ -164,24 +221,11 @@ MainLoop *test(TestType p_type) {
test_parser(code, test, lines);
break;
case TEST_COMPILER:
+ test_compiler(code, test, lines);
+ break;
case TEST_BYTECODE:
print_line("Not implemented.");
}
-
- return nullptr;
-}
-
-} // namespace TestGDScript
-
-#else
-
-namespace TestGDScript {
-
-MainLoop *test(TestType p_type) {
- ERR_PRINT("The GDScript module is disabled, therefore GDScript tests cannot be used.");
- return nullptr;
}
} // namespace TestGDScript
-
-#endif
diff --git a/tests/test_gdscript.h b/modules/gdscript/tests/test_gdscript.h
index 6595da1430..5aa962dcf8 100644
--- a/tests/test_gdscript.h
+++ b/modules/gdscript/tests/test_gdscript.h
@@ -31,8 +31,6 @@
#ifndef TEST_GDSCRIPT_H
#define TEST_GDSCRIPT_H
-#include "core/os/main_loop.h"
-
namespace TestGDScript {
enum TestType {
@@ -42,7 +40,8 @@ enum TestType {
TEST_BYTECODE,
};
-MainLoop *test(TestType p_type);
+void test(TestType p_type);
+
} // namespace TestGDScript
#endif // TEST_GDSCRIPT_H
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 79220da7c2..57fbc5bfc0 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -10,7 +10,7 @@
Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link>
+ <link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link>
</tutorials>
<methods>
<method name="clear">
@@ -205,7 +205,7 @@
GridMaps act as static bodies, meaning they aren't affected by gravity or other forces. They only affect other physics bodies that collide with them.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this GridMap detects collisions in.
+ The physics layers this GridMap detects collisions in. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
<member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library">
The assigned [MeshLibrary].
diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp
index 7bb70b098f..320da182f8 100644
--- a/modules/jsonrpc/jsonrpc.cpp
+++ b/modules/jsonrpc/jsonrpc.cpp
@@ -98,6 +98,10 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem
if (p_action.get_type() == Variant::DICTIONARY) {
Dictionary dict = p_action;
String method = dict.get("method", "");
+ if (method.begins_with("$/")) {
+ return ret;
+ }
+
Array args;
if (dict.has("params")) {
Variant params = dict.get("params", Variant());
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 501bfff075..12a982df6e 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -43,8 +43,8 @@
#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
-#include "mbedtls/pem.h"
#include <mbedtls/debug.h>
+#include <mbedtls/pem.h>
CryptoKey *CryptoKeyMbedTLS::create() {
return memnew(CryptoKeyMbedTLS);
@@ -294,20 +294,15 @@ Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoK
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_PRINT("Generated invalid certificate: " + itos(err));
- return nullptr;
- }
-
+ int ret = mbedtls_x509write_crt_pem(&crt, buf, 4096, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_mpi_free(&serial);
mbedtls_x509write_crt_free(&crt);
+ ERR_FAIL_COND_V_MSG(ret != 0, nullptr, "Failed to generate certificate: " + itos(ret));
+ buf[4095] = '\0'; // Make sure strlen can't fail.
+
+ Ref<X509CertificateMbedTLS> out;
+ out.instance();
+ out->load_from_memory(buf, strlen((char *)buf) + 1); // Use strlen to find correct output size.
return out;
}
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 3e771e06f0..6057004166 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -1,6 +1,5 @@
import os
import os.path
-import sys
import subprocess
from SCons.Script import Dir, Environment
@@ -397,9 +396,8 @@ def configure(env, env_mono):
mono_root = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip()
if tools_enabled:
+ # Only supported for editor builds.
copy_mono_root_files(env, mono_root)
- else:
- print("Ignoring option: 'copy_mono_root'; only available for builds with 'tools' enabled.")
def make_template_dir(env, mono_root):
diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py
index 3090a4759a..0ec7e2f433 100644
--- a/modules/mono/build_scripts/mono_reg_utils.py
+++ b/modules/mono/build_scripts/mono_reg_utils.py
@@ -9,7 +9,7 @@ if os.name == "nt":
def _reg_open_key(key, subkey):
try:
return winreg.OpenKey(key, subkey)
- except (WindowsError, OSError):
+ except OSError:
if platform.architecture()[0] == "32bit":
bitness_sam = winreg.KEY_WOW64_64KEY
else:
@@ -37,7 +37,7 @@ def _find_mono_in_reg(subkey, bits):
with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
value = winreg.QueryValueEx(hKey, "SdkInstallRoot")[0]
return value
- except (WindowsError, OSError):
+ except OSError:
return None
@@ -48,7 +48,7 @@ def _find_mono_in_reg_old(subkey, bits):
if default_clr:
return _find_mono_in_reg(subkey + "\\" + default_clr, bits)
return None
- except (WindowsError, EnvironmentError):
+ except OSError:
return None
@@ -97,7 +97,7 @@ def find_msbuild_tools_path_reg():
raise ValueError("Cannot find `installationPath` entry")
except ValueError as e:
print("Error reading output from vswhere: " + e.message)
- except WindowsError:
+ except OSError:
pass # Fine, vswhere not found
except (subprocess.CalledProcessError, OSError):
pass
@@ -109,5 +109,5 @@ def find_msbuild_tools_path_reg():
with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0]
return value
- except (WindowsError, OSError):
+ except OSError:
return ""
diff --git a/modules/mono/build_scripts/solution_builder.py b/modules/mono/build_scripts/solution_builder.py
index 03f4e57f02..6a621c3c8b 100644
--- a/modules/mono/build_scripts/solution_builder.py
+++ b/modules/mono/build_scripts/solution_builder.py
@@ -8,9 +8,6 @@ def find_dotnet_cli():
import os.path
if os.name == "nt":
- windows_exts = os.environ["PATHEXT"]
- windows_exts = windows_exts.split(os.pathsep) if windows_exts else []
-
for hint_dir in os.environ["PATH"].split(os.pathsep):
hint_dir = hint_dir.strip('"')
hint_path = os.path.join(hint_dir, "dotnet")
diff --git a/modules/mono/config.py b/modules/mono/config.py
index cd659057ef..d060ae9b28 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -23,18 +23,16 @@ def configure(env):
envvars.Add(
PathVariable(
"mono_prefix",
- "Path to the mono installation directory for the target platform and architecture",
+ "Path to the Mono installation directory for the target platform and architecture",
"",
PathVariable.PathAccept,
)
)
- envvars.Add(BoolVariable("mono_static", "Statically link mono", default_mono_static))
- envvars.Add(BoolVariable("mono_glue", "Build with the mono glue sources", True))
+ envvars.Add(BoolVariable("mono_static", "Statically link Mono", default_mono_static))
+ envvars.Add(BoolVariable("mono_glue", "Build with the Mono glue sources", True))
envvars.Add(BoolVariable("build_cil", "Build C# solutions", True))
envvars.Add(
- BoolVariable(
- "copy_mono_root", "Make a copy of the mono installation directory to bundle with the editor", False
- )
+ BoolVariable("copy_mono_root", "Make a copy of the Mono installation directory to bundle with the editor", True)
)
# TODO: It would be great if this could be detected automatically instead
diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml
index e1e9d1381f..45a6f991bf 100644
--- a/modules/mono/doc_classes/CSharpScript.xml
+++ b/modules/mono/doc_classes/CSharpScript.xml
@@ -8,7 +8,7 @@
See also [GodotSharp].
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/scripting/c_sharp/index.html</link>
+ <link title="C# tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/c_sharp/index.html</link>
</tutorials>
<methods>
<method name="new" qualifiers="vararg">
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index dfc59e6ccb..4f8faffde2 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -88,7 +88,7 @@
<PropertyGroup>
<!-- ExportDebug also defines DEBUG like Debug does. -->
<DefineConstants Condition=" '$(Configuration)' == 'ExportDebug' ">$(DefineConstants);DEBUG</DefineConstants>
- <!-- Debug defines TOOLS to differenciate between Debug and ExportDebug configurations. -->
+ <!-- Debug defines TOOLS to differentiate between Debug and ExportDebug configurations. -->
<DefineConstants Condition=" '$(Configuration)' == 'Debug' ">$(DefineConstants);TOOLS</DefineConstants>
<DefineConstants>$(GodotDefineConstants);$(DefineConstants)</DefineConstants>
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
index e6b0e8f1df..b217ae4bf7 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Runtime.InteropServices;
namespace GodotTools.Core
{
@@ -14,14 +15,18 @@ namespace GodotTools.Core
if (Path.DirectorySeparatorChar == '\\')
dir = dir.Replace("/", "\\") + "\\";
- Uri fullPath = new Uri(Path.GetFullPath(path), UriKind.Absolute);
- Uri relRoot = new Uri(Path.GetFullPath(dir), UriKind.Absolute);
+ var fullPath = new Uri(Path.GetFullPath(path), UriKind.Absolute);
+ var relRoot = new Uri(Path.GetFullPath(dir), UriKind.Absolute);
- return relRoot.MakeRelativeUri(fullPath).ToString();
+ // MakeRelativeUri converts spaces to %20, hence why we need UnescapeDataString
+ return Uri.UnescapeDataString(relRoot.MakeRelativeUri(fullPath).ToString());
}
public static string NormalizePath(this string path)
{
+ if (string.IsNullOrEmpty(path))
+ return path;
+
bool rooted = path.IsAbsolutePath();
path = path.Replace('\\', '/');
@@ -31,7 +36,17 @@ namespace GodotTools.Core
path = string.Join(Path.DirectorySeparatorChar.ToString(), parts).Trim();
- return rooted ? Path.DirectorySeparatorChar + path : path;
+ if (!rooted)
+ return path;
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ string maybeDrive = parts[0];
+ if (maybeDrive.Length == 2 && maybeDrive[1] == ':')
+ return path; // Already has drive letter
+ }
+
+ return Path.DirectorySeparatorChar + path;
}
private static readonly string DriveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
@@ -45,7 +60,7 @@ namespace GodotTools.Core
public static string ToSafeDirName(this string dirName, bool allowDirSeparator = false)
{
- var invalidChars = new List<string> { ":", "*", "?", "\"", "<", ">", "|" };
+ var invalidChars = new List<string> {":", "*", "?", "\"", "<", ">", "|"};
if (allowDirSeparator)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
index 6f318aab4a..cc0da44a13 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
@@ -2,6 +2,7 @@ using GodotTools.Core;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text;
using System.Text.RegularExpressions;
namespace GodotTools.ProjectEditor
@@ -88,7 +89,7 @@ namespace GodotTools.ProjectEditor
string solutionPath = Path.Combine(DirectoryPath, Name + ".sln");
string content = string.Format(SolutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg);
- File.WriteAllText(solutionPath, content);
+ File.WriteAllText(solutionPath, content, Encoding.UTF8); // UTF-8 with BOM
}
public DotNetSolution(string name)
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
index 41c94f19c8..e4d6b2e010 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
@@ -20,7 +20,7 @@
<ItemGroup>
<None Include="MSBuild.exe" CopyToOutputDirectory="Always" />
</ItemGroup>
- <Target Name="CopyMSBuildStubWindows" AfterTargets="Build" Condition="$([MSBuild]::IsOsPlatform(Windows))">
+ <Target Name="CopyMSBuildStubWindows" AfterTargets="Build" Condition=" '$(GodotPlatform)' == 'windows' Or ( '$(GodotPlatform)' == '' And '$(OS)' == 'Windows_NT' ) ">
<PropertyGroup>
<GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)/bin/GodotSharp</GodotOutputDataDir>
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 4041c56597..4e2c0f17cc 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -61,10 +61,9 @@ namespace GodotTools.ProjectEditor
if (item.ItemType != itemType)
continue;
- string normalizedExclude = item.Exclude.NormalizePath();
-
- var glob = MSBuildGlob.Parse(normalizedExclude);
+ string normalizedRemove = item.Remove.NormalizePath();
+ var glob = MSBuildGlob.Parse(normalizedRemove);
excluded.AddRange(includedFiles.Where(includedFile => glob.IsMatch(includedFile)));
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index f36e581a5f..7bfba779fb 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -161,8 +161,21 @@ namespace GodotTools.Build
// Try to find 15.0 with vswhere
- string vsWherePath = Environment.GetEnvironmentVariable(Internal.GodotIs32Bits() ? "ProgramFiles" : "ProgramFiles(x86)");
- vsWherePath += "\\Microsoft Visual Studio\\Installer\\vswhere.exe";
+ var envNames = Internal.GodotIs32Bits() ? new[] { "ProgramFiles", "ProgramW6432" } : new[] { "ProgramFiles(x86)", "ProgramFiles" };
+
+ string vsWherePath = null;
+ foreach (var envName in envNames)
+ {
+ vsWherePath = Environment.GetEnvironmentVariable(envName);
+ if (!string.IsNullOrEmpty(vsWherePath))
+ {
+ vsWherePath += "\\Microsoft Visual Studio\\Installer\\vswhere.exe";
+ if (File.Exists(vsWherePath))
+ break;
+ }
+
+ vsWherePath = null;
+ }
var vsWhereArgs = new[] {"-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"};
diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index a8afb38728..1d800b8151 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -48,7 +48,7 @@ namespace GodotTools
var firstMatch = classes.FirstOrDefault(classDecl =>
classDecl.BaseCount != 0 && // If it doesn't inherit anything, it can't be a Godot.Object.
- classDecl.SearchName != searchName // Filter by the name we're looking for
+ classDecl.SearchName == searchName // Filter by the name we're looking for
);
if (firstMatch == null)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index f60e469503..42ede3f3f3 100755
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -328,7 +328,7 @@ MONO_AOT_MODE_LAST = 1000,
if (lipoExitCode != 0)
throw new Exception($"Command 'lipo' exited with code: {lipoExitCode}");
- // TODO: Add the AOT lib and interpreter libs as device only to supress warnings when targeting the simulator
+ // TODO: Add the AOT lib and interpreter libs as device only to suppress warnings when targeting the simulator
// Add the fat AOT static library to the Xcode project
exporter.AddIosProjectStaticLib(fatOutputFilePath);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index e819848212..599ca94699 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -19,7 +19,7 @@ namespace GodotTools.Export
public class ExportPlugin : EditorExportPlugin
{
[Flags]
- enum I18NCodesets
+ enum I18NCodesets : long
{
None = 0,
CJK = 1,
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 3148458d7e..2a450c5b87 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -31,6 +31,7 @@ namespace GodotTools
private CheckBox aboutDialogCheckBox;
private Button bottomPanelBtn;
+ private Button toolBarBuildButton;
public GodotIdeManager GodotIdeManager { get; private set; }
@@ -127,6 +128,7 @@ namespace GodotTools
{
menuPopup.RemoveItem(menuPopup.GetItemIndex((int)MenuOptions.CreateSln));
bottomPanelBtn.Show();
+ toolBarBuildButton.Show();
}
private void _ShowAboutDialog()
@@ -468,6 +470,15 @@ namespace GodotTools
aboutVBox.AddChild(aboutDialogCheckBox);
}
+ toolBarBuildButton = new Button
+ {
+ Text = "Build",
+ HintTooltip = "Build solution",
+ FocusMode = Control.FocusModeEnum.None
+ };
+ toolBarBuildButton.PressedSignal += _BuildSolutionPressed;
+ AddControlToContainer(CustomControlContainer.Toolbar, toolBarBuildButton);
+
if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
ApplyNecessaryChangesToSolution();
@@ -475,20 +486,12 @@ namespace GodotTools
else
{
bottomPanelBtn.Hide();
+ toolBarBuildButton.Hide();
menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
}
menuPopup.IdPressed += _MenuOptionPressed;
- var buildButton = new Button
- {
- Text = "Build",
- HintTooltip = "Build solution",
- FocusMode = Control.FocusModeEnum.None
- };
- buildButton.PressedSignal += _BuildSolutionPressed;
- AddControlToContainer(CustomControlContainer.Toolbar, buildButton);
-
// External editor settings
EditorDef("mono/editor/external_editor", ExternalEditorId.None);
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index b15e9b060a..2edd8c87dc 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -43,6 +43,16 @@
namespace GodotSharpExport {
+MonoAssemblyName *new_mono_assembly_name() {
+ // Mono has no public API to create an empty MonoAssemblyName and the struct is private.
+ // As such the only way to create it is with a stub name and then clear it.
+
+ MonoAssemblyName *aname = mono_assembly_name_new("stub");
+ CRASH_COND(aname == nullptr);
+ mono_assembly_name_free(aname); // Frees the string fields, not the struct
+ return aname;
+}
+
struct AssemblyRefInfo {
String name;
uint16_t major;
@@ -67,7 +77,7 @@ AssemblyRefInfo get_assemblyref_name(MonoImage *p_image, int index) {
};
}
-Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
+Error get_assembly_dependencies(GDMonoAssembly *p_assembly, MonoAssemblyName *reusable_aname, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
MonoImage *image = p_assembly->get_image();
for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) {
@@ -79,26 +89,16 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
continue;
}
- GDMonoAssembly *ref_assembly = nullptr;
-
- {
- MonoAssemblyName *ref_aname = mono_assembly_name_new("A"); // We can't allocate an empty MonoAssemblyName, hence "A"
- CRASH_COND(ref_aname == nullptr);
- SCOPE_EXIT {
- mono_assembly_name_free(ref_aname);
- mono_free(ref_aname);
- };
-
- mono_assembly_get_assemblyref(image, i, ref_aname);
+ mono_assembly_get_assemblyref(image, i, reusable_aname);
- if (!GDMono::get_singleton()->load_assembly(ref_name, ref_aname, &ref_assembly, /* refonly: */ true, p_search_dirs)) {
- ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
- }
-
- r_assembly_dependencies[ref_name] = ref_assembly->get_path();
+ GDMonoAssembly *ref_assembly = NULL;
+ if (!GDMono::get_singleton()->load_assembly(ref_name, reusable_aname, &ref_assembly, /* refonly: */ true, p_search_dirs)) {
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
}
- Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies);
+ r_assembly_dependencies[ref_name] = ref_assembly->get_path();
+
+ Error err = get_assembly_dependencies(ref_assembly, reusable_aname, p_search_dirs, r_assembly_dependencies);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
@@ -130,7 +130,10 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
- Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
+ MonoAssemblyName *reusable_aname = new_mono_assembly_name();
+ SCOPE_EXIT { mono_free(reusable_aname); };
+
+ Error err = get_assembly_dependencies(assembly, reusable_aname, search_dirs, r_assembly_dependencies);
if (err != OK) {
return err;
}
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
index 430c82953e..f7d6e7e302 100644
--- a/modules/mono/editor/script_class_parser.cpp
+++ b/modules/mono/editor/script_class_parser.cpp
@@ -151,7 +151,7 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
case '"': {
bool verbatim = idx != 0 && code[idx - 1] == '@';
- CharType begin_str = code[idx];
+ char32_t begin_str = code[idx];
idx++;
String tk_string = String();
while (true) {
@@ -170,13 +170,13 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
} else if (code[idx] == '\\' && !verbatim) {
//escaped characters...
idx++;
- CharType next = code[idx];
+ char32_t next = code[idx];
if (next == 0) {
error_str = "Unterminated String";
error = true;
return TK_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -234,7 +234,7 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
if (code[idx] == '-' || (code[idx] >= '0' && code[idx] <= '9')) {
//a number
- const CharType *rptr;
+ const char32_t *rptr;
double number = String::to_float(&code[idx], &rptr);
idx += (rptr - &code[idx]);
value = number;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index a963810d63..f77d3052f4 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -44,6 +44,15 @@ namespace Godot.Collections
Add(element);
}
+ public Array(params object[] array) : this()
+ {
+ if (array == null)
+ {
+ throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
+ }
+ safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor_MonoArray(array));
+ }
+
internal Array(ArraySafeHandle handle)
{
safeHandle = handle;
@@ -72,6 +81,11 @@ namespace Godot.Collections
return godot_icall_Array_Resize(GetPtr(), newSize);
}
+ public static Array operator +(Array left, Array right)
+ {
+ return new Array(godot_icall_Array_Concatenate(left.GetPtr(), right.GetPtr()));
+ }
+
// IDisposable
public void Dispose()
@@ -155,6 +169,9 @@ namespace Godot.Collections
internal extern static IntPtr godot_icall_Array_Ctor();
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Array_Ctor_MonoArray(System.Array array);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -176,6 +193,9 @@ namespace Godot.Collections
internal extern static void godot_icall_Array_Clear(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Array_Concatenate(IntPtr left, IntPtr right);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -231,6 +251,15 @@ namespace Godot.Collections
objectArray = new Array(collection);
}
+ public Array(params T[] array) : this()
+ {
+ if (array == null)
+ {
+ throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
+ }
+ objectArray = new Array(array);
+ }
+
public Array(Array array)
{
objectArray = array;
@@ -266,6 +295,11 @@ namespace Godot.Collections
return objectArray.Resize(newSize);
}
+ public static Array<T> operator +(Array<T> left, Array<T> right)
+ {
+ return new Array<T>(left.objectArray + right.objectArray);
+ }
+
// IList<T>
public T this[int index]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index 5aba31c622..3f1120575f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -207,7 +207,7 @@ namespace Godot
}
}
- internal Quat RotationQuat()
+ public Quat RotationQuat()
{
Basis orthonormalizedBasis = Orthonormalized();
real_t det = orthonormalizedBasis.Determinant();
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index d851abc6d3..3700a6194f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -565,6 +565,9 @@ namespace Godot
rgba = rgba.Substring(1);
}
+ // If enabled, use 1 hex digit per channel instead of 2.
+ // Other sizes aren't in the HTML/CSS spec but we could add them if desired.
+ bool isShorthand = rgba.Length < 5;
bool alpha;
if (rgba.Length == 8)
@@ -575,47 +578,60 @@ namespace Godot
{
alpha = false;
}
+ else if (rgba.Length == 4)
+ {
+ alpha = true;
+ }
+ else if (rgba.Length == 3)
+ {
+ alpha = false;
+ }
else
{
throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
}
- if (alpha)
+ a = 1.0f;
+ if (isShorthand)
{
- a = ParseCol8(rgba, 6) / 255f;
-
- if (a < 0)
+ r = ParseCol4(rgba, 0) / 15f;
+ g = ParseCol4(rgba, 1) / 15f;
+ b = ParseCol4(rgba, 2) / 15f;
+ if (alpha)
{
- throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba);
+ a = ParseCol4(rgba, 3) / 15f;
}
}
else
{
- a = 1.0f;
+ r = ParseCol8(rgba, 0) / 255f;
+ g = ParseCol8(rgba, 2) / 255f;
+ b = ParseCol8(rgba, 4) / 255f;
+ if (alpha)
+ {
+ a = ParseCol8(rgba, 6) / 255f;
+ }
}
- int from = alpha ? 2 : 0;
-
- r = ParseCol8(rgba, 0) / 255f;
-
if (r < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba);
}
- g = ParseCol8(rgba, 2) / 255f;
-
if (g < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba);
}
- b = ParseCol8(rgba, 4) / 255f;
-
if (b < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba);
}
+
+ if (a < 0)
+ {
+ throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba);
+ }
}
/// <summary>
@@ -751,45 +767,28 @@ namespace Godot
value = max;
}
- private static int ParseCol8(string str, int ofs)
+ private static int ParseCol4(string str, int ofs)
{
- int ig = 0;
+ char character = str[ofs];
- for (int i = 0; i < 2; i++)
+ if (character >= '0' && character <= '9')
{
- int c = str[i + ofs];
- int v;
-
- if (c >= '0' && c <= '9')
- {
- v = c - '0';
- }
- else if (c >= 'a' && c <= 'f')
- {
- v = c - 'a';
- v += 10;
- }
- else if (c >= 'A' && c <= 'F')
- {
- v = c - 'A';
- v += 10;
- }
- else
- {
- return -1;
- }
-
- if (i == 0)
- {
- ig += v * 16;
- }
- else
- {
- ig += v;
- }
+ return character - '0';
+ }
+ else if (character >= 'a' && character <= 'f')
+ {
+ return character + (10 - 'a');
}
+ else if (character >= 'A' && character <= 'F')
+ {
+ return character + (10 - 'A');
+ }
+ return -1;
+ }
- return ig;
+ private static int ParseCol8(string str, int ofs)
+ {
+ return ParseCol4(str, ofs) * 16 + ParseCol4(str, ofs + 1);
}
private String ToHex32(float val)
@@ -828,46 +827,24 @@ namespace Godot
if (color[0] == '#')
{
- color = color.Substring(1, color.Length - 1);
+ color = color.Substring(1);
}
- bool alpha;
-
- switch (color.Length)
+ // Check if the amount of hex digits is valid.
+ int len = color.Length;
+ if (!(len == 3 || len == 4 || len == 6 || len == 8))
{
- case 8:
- alpha = true;
- break;
- case 6:
- alpha = false;
- break;
- default:
- return false;
+ return false;
}
- if (alpha)
- {
- if (ParseCol8(color, 0) < 0)
+ // Check if each hex digit is valid.
+ for (int i = 0; i < len; i++) {
+ if (ParseCol4(color, i) == -1)
{
return false;
}
}
- int from = alpha ? 2 : 0;
-
- if (ParseCol8(color, from + 0) < 0)
- {
- return false;
- }
- if (ParseCol8(color, from + 2) < 0)
- {
- return false;
- }
- if (ParseCol8(color, from + 4) < 0)
- {
- return false;
- }
-
return true;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index 41b4e9367f..bd1dbc1229 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -440,7 +440,12 @@ namespace Godot
// </summary>
public static bool IsAbsPath(this string instance)
{
- return System.IO.Path.IsPathRooted(instance);
+ if (string.IsNullOrEmpty(instance))
+ return false;
+ else if (instance.Length > 1)
+ return instance[0] == '/' || instance[0] == '\\' || instance.Contains(":/") || instance.Contains(":\\");
+ else
+ return instance[0] == '/' || instance[0] == '\\';
}
// <summary>
@@ -448,7 +453,7 @@ namespace Godot
// </summary>
public static bool IsRelPath(this string instance)
{
- return !System.IO.Path.IsPathRooted(instance);
+ return !IsAbsPath(instance);
}
// <summary>
@@ -624,41 +629,46 @@ namespace Godot
return instance.Length;
}
- // <summary>
- // Do a simple expression match, where '*' matches zero or more arbitrary characters and '?' matches any single character except '.'.
- // </summary>
- public static bool ExprMatch(this string instance, string expr, bool caseSensitive)
+ /// <summary>
+ /// Do a simple expression match, where '*' matches zero or more arbitrary characters and '?' matches any single character except '.'.
+ /// </summary>
+ private static bool ExprMatch(this string instance, string expr, bool caseSensitive)
{
- if (expr.Length == 0 || instance.Length == 0)
- return false;
+ // case '\0':
+ if (expr.Length == 0)
+ return instance.Length == 0;
switch (expr[0])
{
- case '\0':
- return instance[0] == 0;
case '*':
- return ExprMatch(expr + 1, instance, caseSensitive) || instance[0] != 0 && ExprMatch(expr, instance + 1, caseSensitive);
+ return ExprMatch(instance, expr.Substring(1), caseSensitive) || (instance.Length > 0 && ExprMatch(instance.Substring(1), expr, caseSensitive));
case '?':
- return instance[0] != 0 && instance[0] != '.' && ExprMatch(expr + 1, instance + 1, caseSensitive);
+ return instance.Length > 0 && instance[0] != '.' && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
default:
- return (caseSensitive ? instance[0] == expr[0] : char.ToUpper(instance[0]) == char.ToUpper(expr[0])) &&
- ExprMatch(expr + 1, instance + 1, caseSensitive);
+ if (instance.Length == 0) return false;
+ return (caseSensitive ? instance[0] == expr[0] : char.ToUpper(instance[0]) == char.ToUpper(expr[0])) && ExprMatch(instance.Substring(1), expr.Substring(1), caseSensitive);
}
}
- // <summary>
- // Do a simple case sensitive expression match, using ? and * wildcards (see [method expr_match]).
- // </summary>
+ /// <summary>
+ /// Do a simple case sensitive expression match, using ? and * wildcards (see [method expr_match]).
+ /// </summary>
public static bool Match(this string instance, string expr, bool caseSensitive = true)
{
+ if (instance.Length == 0 || expr.Length == 0)
+ return false;
+
return instance.ExprMatch(expr, caseSensitive);
}
- // <summary>
- // Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]).
- // </summary>
+ /// <summary>
+ /// Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]).
+ /// </summary>
public static bool MatchN(this string instance, string expr)
{
+ if (instance.Length == 0 || expr.Length == 0)
+ return false;
+
return instance.ExprMatch(expr, caseSensitive: false);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 26bd828a5b..3dff37279b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -670,41 +670,37 @@ namespace Godot
public static bool operator <(Vector2 left, Vector2 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
return left.y < right.y;
}
-
return left.x < right.x;
}
public static bool operator >(Vector2 left, Vector2 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
return left.y > right.y;
}
-
return left.x > right.x;
}
public static bool operator <=(Vector2 left, Vector2 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
return left.y <= right.y;
}
-
return left.x <= right.x;
}
public static bool operator >=(Vector2 left, Vector2 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
return left.y >= right.y;
}
-
return left.x >= right.x;
}
@@ -714,7 +710,6 @@ namespace Godot
{
return Equals((Vector2)obj);
}
-
return false;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index d9b16a6afd..4a4a2a43cd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -713,49 +713,53 @@ namespace Godot
public static bool operator <(Vector3 left, Vector3 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
- if (Mathf.IsEqualApprox(left.y, right.y))
+ if (left.y == right.y)
+ {
return left.z < right.z;
+ }
return left.y < right.y;
}
-
return left.x < right.x;
}
public static bool operator >(Vector3 left, Vector3 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
- if (Mathf.IsEqualApprox(left.y, right.y))
+ if (left.y == right.y)
+ {
return left.z > right.z;
+ }
return left.y > right.y;
}
-
return left.x > right.x;
}
public static bool operator <=(Vector3 left, Vector3 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
- if (Mathf.IsEqualApprox(left.y, right.y))
+ if (left.y == right.y)
+ {
return left.z <= right.z;
+ }
return left.y < right.y;
}
-
return left.x < right.x;
}
public static bool operator >=(Vector3 left, Vector3 right)
{
- if (Mathf.IsEqualApprox(left.x, right.x))
+ if (left.x == right.x)
{
- if (Mathf.IsEqualApprox(left.y, right.y))
+ if (left.y == right.y)
+ {
return left.z >= right.z;
+ }
return left.y > right.y;
}
-
return left.x > right.x;
}
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index 766b00d612..3313e8cb77 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -104,10 +104,31 @@ void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
}
}
+Array *godot_icall_Array_Ctor_MonoArray(MonoArray *mono_array) {
+ Array *godot_array = memnew(Array);
+ unsigned int count = mono_array_length(mono_array);
+ godot_array->resize(count);
+ for (unsigned int i = 0; i < count; i++) {
+ MonoObject *item = mono_array_get(mono_array, MonoObject *, i);
+ godot_icall_Array_SetAt(godot_array, i, item);
+ }
+ return godot_array;
+}
+
Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep) {
return memnew(Array(ptr->duplicate(deep)));
}
+Array *godot_icall_Array_Concatenate(Array *left, Array *right) {
+ int count = left->size() + right->size();
+ Array *new_array = memnew(Array(left->duplicate(false)));
+ new_array->resize(count);
+ for (unsigned int i = 0; i < (unsigned int)right->size(); i++) {
+ new_array->operator[](i + left->size()) = right->operator[](i);
+ }
+ return new_array;
+}
+
int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
}
@@ -284,6 +305,7 @@ MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr) {
void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", (void *)godot_icall_Array_Ctor_MonoArray);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", (void *)godot_icall_Array_At_Generic);
@@ -291,6 +313,7 @@ void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", (void *)godot_icall_Array_Concatenate);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", (void *)godot_icall_Array_Duplicate);
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 9dbeee57ce..6e351001d4 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -107,7 +107,7 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]]
GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, image, assembly));
#ifdef GD_MONO_HOT_RELOAD
- const char *path = mono_image_get_filename(image);
+ String path = String::utf8(mono_image_get_filename(image));
if (FileAccess::exists(path)) {
gdassembly->modified_time = FileAccess::get_modified_time(path);
}
@@ -464,7 +464,9 @@ GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_a
if (!assembly) {
assembly = _load_assembly_search(p_name, p_aname, p_refonly, p_search_dirs);
- ERR_FAIL_NULL_V(assembly, nullptr);
+ if (!assembly) {
+ return nullptr;
+ }
}
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
@@ -487,7 +489,9 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_
if (!assembly) {
assembly = _real_load_assembly_from(p_path, p_refonly);
- ERR_FAIL_NULL_V(assembly, nullptr);
+ if (!assembly) {
+ return nullptr;
+ }
}
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index c5a988b8c3..b8ee0204c4 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -64,25 +64,32 @@ static int get_log_level_id(const char *p_log_level) {
return -1;
}
+static String make_text(const char *log_domain, const char *log_level, const char *message) {
+ String text(message);
+ text += " (in domain ";
+ text += log_domain;
+ if (log_level) {
+ text += ", ";
+ text += log_level;
+ }
+ text += ")";
+ return text;
+}
+
void GDMonoLog::mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *) {
FileAccess *f = GDMonoLog::get_singleton()->log_file;
if (GDMonoLog::get_singleton()->log_level_id >= get_log_level_id(log_level)) {
- String text(message);
- text += " (in domain ";
- text += log_domain;
- if (log_level) {
- text += ", ";
- text += log_level;
- }
- text += ")\n";
+ String text = make_text(log_domain, log_level, message);
+ text += "\n";
f->seek_end();
f->store_string(text);
}
if (fatal) {
- ERR_PRINT("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'.");
+ String text = make_text(log_domain, log_level, message);
+ ERR_PRINT("Mono: FATAL ERROR '" + text + "', ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'.");
// Make sure to flush before aborting
f->flush();
f->close();
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 6d7d5f76cd..c460e283ea 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -311,44 +311,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
return false;
}
-String mono_to_utf8_string(MonoString *p_mono_string) {
- MonoError error;
- char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
-
- if (!mono_error_ok(&error)) {
- ERR_PRINT(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'.");
- mono_error_cleanup(&error);
- return String();
- }
-
- String ret = String::utf8(utf8);
-
- mono_free(utf8);
-
- return ret;
-}
-
-String mono_to_utf16_string(MonoString *p_mono_string) {
- int len = mono_string_length(p_mono_string);
- String ret;
-
- if (len == 0) {
- return ret;
- }
-
- ret.resize(len + 1);
- ret.set(len, 0);
-
- CharType *src = (CharType *)mono_string_chars(p_mono_string);
- CharType *dst = ret.ptrw();
-
- for (int i = 0; i < len; i++) {
- dst[i] = src[i];
- }
-
- return ret;
-}
-
MonoObject *variant_to_mono_object(const Variant *p_var) {
ManagedType type;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 4ff330fd43..a1fd975916 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -69,15 +69,11 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
// String
-String mono_to_utf8_string(MonoString *p_mono_string);
-String mono_to_utf16_string(MonoString *p_mono_string);
-
_FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) {
- if constexpr (sizeof(CharType) == 2) {
- return mono_to_utf16_string(p_mono_string);
- }
-
- return mono_to_utf8_string(p_mono_string);
+ char32_t *utf32 = (char32_t *)mono_string_to_utf32(p_mono_string);
+ String ret = String(utf32);
+ mono_free(utf32);
+ return ret;
}
_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) {
@@ -88,20 +84,8 @@ _FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) {
return mono_string_to_godot_not_null(p_mono_string);
}
-_FORCE_INLINE_ MonoString *mono_from_utf8_string(const String &p_string) {
- return mono_string_new(mono_domain_get(), p_string.utf8().get_data());
-}
-
-_FORCE_INLINE_ MonoString *mono_from_utf16_string(const String &p_string) {
- return mono_string_from_utf16((mono_unichar2 *)p_string.c_str());
-}
-
_FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
- if constexpr (sizeof(CharType) == 2) {
- return mono_from_utf16_string(p_string);
- }
-
- return mono_from_utf8_string(p_string);
+ return mono_string_from_utf32((mono_unichar4 *)(p_string.get_data()));
}
// Variant
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 9db4a5f3f0..5958bf3cc1 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -44,7 +44,8 @@
if (unlikely(m_exc != nullptr)) { \
GDMonoUtils::debug_unhandled_exception(m_exc); \
GD_UNREACHABLE(); \
- }
+ } else \
+ ((void)0)
namespace GDMonoUtils {
@@ -162,20 +163,24 @@ StringName get_native_godot_class_name(GDMonoClass *p_class);
#define GD_MONO_BEGIN_RUNTIME_INVOKE \
int &_runtime_invoke_count_ref = GDMonoUtils::get_runtime_invoke_count_ref(); \
- _runtime_invoke_count_ref += 1;
+ _runtime_invoke_count_ref += 1; \
+ ((void)0)
-#define GD_MONO_END_RUNTIME_INVOKE \
- _runtime_invoke_count_ref -= 1;
+#define GD_MONO_END_RUNTIME_INVOKE \
+ _runtime_invoke_count_ref -= 1; \
+ ((void)0)
#define GD_MONO_SCOPE_THREAD_ATTACH \
GDMonoUtils::ScopeThreadAttach __gdmono__scope__thread__attach__; \
- (void)__gdmono__scope__thread__attach__;
+ (void)__gdmono__scope__thread__attach__; \
+ ((void)0)
#ifdef DEBUG_ENABLED
-#define GD_MONO_ASSERT_THREAD_ATTACHED \
- { CRASH_COND(!GDMonoUtils::is_thread_attached()); }
+#define GD_MONO_ASSERT_THREAD_ATTACHED \
+ CRASH_COND(!GDMonoUtils::is_thread_attached()); \
+ ((void)0)
#else
-#define GD_MONO_ASSERT_THREAD_ATTACHED
+#define GD_MONO_ASSERT_THREAD_ATTACHED ((void)0)
#endif
#endif // GD_MONOUTILS_H
diff --git a/modules/mono/register_types.h b/modules/mono/register_types.h
index 7fd0d24eb0..e30d9a8abd 100644
--- a/modules/mono/register_types.h
+++ b/modules/mono/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef MONO_REGISTER_TYPES_H
+#define MONO_REGISTER_TYPES_H
+
void register_mono_types();
void unregister_mono_types();
+
+#endif // MONO_REGISTER_TYPES_H
diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h
index dc542477f5..c76619cca4 100644
--- a/modules/mono/utils/macros.h
+++ b/modules/mono/utils/macros.h
@@ -46,7 +46,7 @@
#define GD_UNREACHABLE() \
CRASH_NOW(); \
do { \
- } while (true);
+ } while (true)
#endif
namespace gdmono {
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index e0cf916a01..a619f0b975 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -71,12 +71,12 @@ LONG _RegKeyQueryString(HKEY hKey, const String &p_value_name, String &r_value)
buffer.resize(512);
DWORD dwBufferSize = buffer.size();
- LONG res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
+ LONG res = RegQueryValueExW(hKey, (LPCWSTR)(p_value_name.utf16().get_data()), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
if (res == ERROR_MORE_DATA) {
// dwBufferSize now contains the actual size
buffer.resize(dwBufferSize);
- res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
+ res = RegQueryValueExW(hKey, (LPCWSTR)(p_value_name.utf16().get_data()), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
}
if (res == ERROR_SUCCESS) {
@@ -90,7 +90,7 @@ LONG _RegKeyQueryString(HKEY hKey, const String &p_value_name, String &r_value)
LONG _find_mono_in_reg(const String &p_subkey, MonoRegInfo &r_info, bool p_old_reg = false) {
HKEY hKey;
- LONG res = _RegOpenKey(HKEY_LOCAL_MACHINE, p_subkey.c_str(), &hKey);
+ LONG res = _RegOpenKey(HKEY_LOCAL_MACHINE, (LPCWSTR)(p_subkey.utf16().get_data()), &hKey);
if (res != ERROR_SUCCESS)
goto cleanup;
@@ -127,7 +127,7 @@ LONG _find_mono_in_reg_old(const String &p_subkey, MonoRegInfo &r_info) {
String default_clr;
HKEY hKey;
- LONG res = _RegOpenKey(HKEY_LOCAL_MACHINE, p_subkey.c_str(), &hKey);
+ LONG res = _RegOpenKey(HKEY_LOCAL_MACHINE, (LPCWSTR)(p_subkey.utf16().get_data()), &hKey);
if (res != ERROR_SUCCESS)
goto cleanup;
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index ccfaf5aba7..5d1abd0c09 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -54,12 +54,16 @@ String cwd() {
#ifdef WINDOWS_ENABLED
const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr);
- String buffer;
+ Char16String buffer;
buffer.resize((int)expected_size);
- if (::GetCurrentDirectoryW(expected_size, buffer.ptrw()) == 0)
+ if (::GetCurrentDirectoryW(expected_size, (wchar_t *)buffer.ptrw()) == 0)
return ".";
- return buffer.simplify_path();
+ String result;
+ if (result.parse_utf16(buffer.ptr())) {
+ return ".";
+ }
+ return result.simplify_path();
#else
char buffer[PATH_MAX];
if (::getcwd(buffer, sizeof(buffer)) == nullptr) {
@@ -86,7 +90,7 @@ String abspath(const String &p_path) {
String realpath(const String &p_path) {
#ifdef WINDOWS_ENABLED
// Open file without read/write access
- HANDLE hFile = ::CreateFileW(p_path.c_str(), 0,
+ HANDLE hFile = ::CreateFileW((LPCWSTR)(p_path.utf16().get_data()), 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
@@ -100,12 +104,18 @@ String realpath(const String &p_path) {
return p_path;
}
- String buffer;
+ Char16String buffer;
buffer.resize((int)expected_size);
- ::GetFinalPathNameByHandleW(hFile, buffer.ptrw(), expected_size, FILE_NAME_NORMALIZED);
+ ::GetFinalPathNameByHandleW(hFile, (wchar_t *)buffer.ptrw(), expected_size, FILE_NAME_NORMALIZED);
::CloseHandle(hFile);
- return buffer.simplify_path();
+
+ String result;
+ if (result.parse_utf16(buffer.ptr())) {
+ return p_path;
+ }
+
+ return result.simplify_path();
#elif UNIX_ENABLED
char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr);
@@ -130,7 +140,7 @@ String join(const String &p_a, const String &p_b) {
return p_b;
}
- const CharType a_last = p_a[p_a.length() - 1];
+ const char32_t a_last = p_a[p_a.length() - 1];
if ((a_last == '/' || a_last == '\\') ||
(p_b.size() > 0 && (p_b[0] == '/' || p_b[0] == '\\'))) {
return p_a + p_b;
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index f8d9804de4..65da4328f6 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -49,7 +49,7 @@ int sfind(const String &p_text, int p_from) {
return -1;
}
- const CharType *src = p_text.c_str();
+ const char32_t *src = p_text.get_data();
for (int i = p_from; i <= (len - src_len); i++) {
bool found = true;
@@ -64,7 +64,7 @@ int sfind(const String &p_text, int p_from) {
found = src[read_pos] == '%';
break;
case 1: {
- CharType c = src[read_pos];
+ char32_t c = src[read_pos];
found = src[read_pos] == 's' || (c >= '0' && c <= '4');
break;
}
@@ -121,7 +121,7 @@ String sformat(const String &p_text, const Variant &p1, const Variant &p2, const
int result = 0;
while ((result = sfind(p_text, search_from)) >= 0) {
- CharType c = p_text[result + 1];
+ char32_t c = p_text[result + 1];
int req_index = (c == 's' ? findex++ : c - '0');
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 36c0913f62..050dce1aab 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -213,10 +213,12 @@ static void _compress_pvrtc4(Image *p_img) {
int ofs, size, w, h;
img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
Javelin::RgbaBitmap bm(w, h);
+ void *dst = (void *)bm.GetData();
+ copymem(dst, &r[ofs], size);
+ Javelin::ColorRgba<unsigned char> *dp = bm.GetData();
for (int j = 0; j < size / 4; j++) {
- Javelin::ColorRgba<unsigned char> *dp = bm.GetData();
- /* red and Green colors are swapped. */
- new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]);
+ /* red and blue colors are swapped. */
+ SWAP(dp[j].r, dp[j].b);
}
new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm);
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index 50ca01067b..c10a276eae 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -156,26 +156,13 @@ void RegExMatch::_bind_methods() {
}
void RegEx::_pattern_info(uint32_t what, void *where) const {
- if (sizeof(CharType) == 2) {
- pcre2_pattern_info_16((pcre2_code_16 *)code, what, where);
-
- } else {
- pcre2_pattern_info_32((pcre2_code_32 *)code, what, where);
- }
+ pcre2_pattern_info_32((pcre2_code_32 *)code, what, where);
}
void RegEx::clear() {
- if (sizeof(CharType) == 2) {
- if (code) {
- pcre2_code_free_16((pcre2_code_16 *)code);
- code = nullptr;
- }
-
- } else {
- if (code) {
- pcre2_code_free_32((pcre2_code_32 *)code);
- code = nullptr;
- }
+ if (code) {
+ pcre2_code_free_32((pcre2_code_32 *)code);
+ code = nullptr;
}
}
@@ -187,39 +174,20 @@ Error RegEx::compile(const String &p_pattern) {
PCRE2_SIZE offset;
uint32_t flags = PCRE2_DUPNAMES;
- if (sizeof(CharType) == 2) {
- pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
- pcre2_compile_context_16 *cctx = pcre2_compile_context_create_16(gctx);
- PCRE2_SPTR16 p = (PCRE2_SPTR16)pattern.c_str();
-
- code = pcre2_compile_16(p, pattern.length(), flags, &err, &offset, cctx);
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_compile_context_32 *cctx = pcre2_compile_context_create_32(gctx);
+ PCRE2_SPTR32 p = (PCRE2_SPTR32)pattern.get_data();
- pcre2_compile_context_free_16(cctx);
+ code = pcre2_compile_32(p, pattern.length(), flags, &err, &offset, cctx);
- if (!code) {
- PCRE2_UCHAR16 buf[256];
- pcre2_get_error_message_16(err, buf, 256);
- String message = String::num(offset) + ": " + String((const CharType *)buf);
- ERR_PRINT(message.utf8());
- return FAILED;
- }
+ pcre2_compile_context_free_32(cctx);
- } else {
- pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
- pcre2_compile_context_32 *cctx = pcre2_compile_context_create_32(gctx);
- PCRE2_SPTR32 p = (PCRE2_SPTR32)pattern.c_str();
-
- code = pcre2_compile_32(p, pattern.length(), flags, &err, &offset, cctx);
-
- pcre2_compile_context_free_32(cctx);
-
- if (!code) {
- PCRE2_UCHAR32 buf[256];
- pcre2_get_error_message_32(err, buf, 256);
- String message = String::num(offset) + ": " + String((const CharType *)buf);
- ERR_PRINT(message.utf8());
- return FAILED;
- }
+ if (!code) {
+ PCRE2_UCHAR32 buf[256];
+ pcre2_get_error_message_32(err, buf, 256);
+ String message = String::num(offset) + ": " + String((const char32_t *)buf);
+ ERR_PRINT(message.utf8());
+ return FAILED;
}
return OK;
}
@@ -234,69 +202,39 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
length = p_end;
}
- if (sizeof(CharType) == 2) {
- pcre2_code_16 *c = (pcre2_code_16 *)code;
- pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
- pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
- PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str();
-
- pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx);
-
- int res = pcre2_match_16(c, s, length, p_offset, 0, match, mctx);
+ pcre2_code_32 *c = (pcre2_code_32 *)code;
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
+ PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.get_data();
- if (res < 0) {
- pcre2_match_data_free_16(match);
- return nullptr;
- }
-
- uint32_t size = pcre2_get_ovector_count_16(match);
- PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_16(match);
-
- result->data.resize(size);
-
- for (uint32_t i = 0; i < size; i++) {
- result->data.write[i].start = ovector[i * 2];
- result->data.write[i].end = ovector[i * 2 + 1];
- }
-
- pcre2_match_data_free_16(match);
- pcre2_match_context_free_16(mctx);
-
- } else {
- pcre2_code_32 *c = (pcre2_code_32 *)code;
- pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
- pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
- PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str();
+ pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
- pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
+ int res = pcre2_match_32(c, s, length, p_offset, 0, match, mctx);
- int res = pcre2_match_32(c, s, length, p_offset, 0, match, mctx);
-
- if (res < 0) {
- pcre2_match_data_free_32(match);
- pcre2_match_context_free_32(mctx);
+ if (res < 0) {
+ pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
- return nullptr;
- }
+ return nullptr;
+ }
- uint32_t size = pcre2_get_ovector_count_32(match);
- PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(match);
+ uint32_t size = pcre2_get_ovector_count_32(match);
+ PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(match);
- result->data.resize(size);
+ result->data.resize(size);
- for (uint32_t i = 0; i < size; i++) {
- result->data.write[i].start = ovector[i * 2];
- result->data.write[i].end = ovector[i * 2 + 1];
- }
-
- pcre2_match_data_free_32(match);
- pcre2_match_context_free_32(mctx);
+ for (uint32_t i = 0; i < size; i++) {
+ result->data.write[i].start = ovector[i * 2];
+ result->data.write[i].end = ovector[i * 2 + 1];
}
+ pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
+
result->subject = p_subject;
uint32_t count;
- const CharType *table;
+ const char32_t *table;
uint32_t entry_size;
_pattern_info(PCRE2_INFO_NAMECOUNT, &count);
@@ -304,7 +242,7 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
_pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
for (uint32_t i = 0; i < count; i++) {
- CharType id = table[i * entry_size];
+ char32_t id = table[i * entry_size];
if (result->data[id].start == -1) {
continue;
}
@@ -344,7 +282,7 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
const int safety_zone = 1;
PCRE2_SIZE olength = p_subject.length() + 1; // space for output string and one terminating \0 character
- Vector<CharType> output;
+ Vector<char32_t> output;
output.resize(olength + safety_zone);
uint32_t flags = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
@@ -357,55 +295,28 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
length = p_end;
}
- if (sizeof(CharType) == 2) {
- pcre2_code_16 *c = (pcre2_code_16 *)code;
- pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
- pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
- PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str();
- PCRE2_SPTR16 r = (PCRE2_SPTR16)p_replacement.c_str();
- PCRE2_UCHAR16 *o = (PCRE2_UCHAR16 *)output.ptrw();
+ pcre2_code_32 *c = (pcre2_code_32 *)code;
+ pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
+ pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
+ PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.get_data();
+ PCRE2_SPTR32 r = (PCRE2_SPTR32)p_replacement.get_data();
+ PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.ptrw();
- pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx);
-
- int res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
-
- if (res == PCRE2_ERROR_NOMEMORY) {
- output.resize(olength + safety_zone);
- o = (PCRE2_UCHAR16 *)output.ptrw();
- res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
- }
+ pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
- pcre2_match_data_free_16(match);
- pcre2_match_context_free_16(mctx);
+ int res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
- if (res < 0) {
- return String();
- }
-
- } else {
- pcre2_code_32 *c = (pcre2_code_32 *)code;
- pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
- pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
- PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str();
- PCRE2_SPTR32 r = (PCRE2_SPTR32)p_replacement.c_str();
- PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.ptrw();
-
- pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx);
-
- int res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
-
- if (res == PCRE2_ERROR_NOMEMORY) {
- output.resize(olength + safety_zone);
- o = (PCRE2_UCHAR32 *)output.ptrw();
- res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
- }
+ if (res == PCRE2_ERROR_NOMEMORY) {
+ output.resize(olength + safety_zone);
+ o = (PCRE2_UCHAR32 *)output.ptrw();
+ res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength);
+ }
- pcre2_match_data_free_32(match);
- pcre2_match_context_free_32(mctx);
+ pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
- if (res < 0) {
- return String();
- }
+ if (res < 0) {
+ return String();
}
return String(output.ptr(), olength);
@@ -435,7 +346,7 @@ Array RegEx::get_names() const {
ERR_FAIL_COND_V(!is_valid(), result);
uint32_t count;
- const CharType *table;
+ const char32_t *table;
uint32_t entry_size;
_pattern_info(PCRE2_INFO_NAMECOUNT, &count);
@@ -453,39 +364,21 @@ Array RegEx::get_names() const {
}
RegEx::RegEx() {
- if (sizeof(CharType) == 2) {
- general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
-
- } else {
- general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
- }
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
code = nullptr;
}
RegEx::RegEx(const String &p_pattern) {
- if (sizeof(CharType) == 2) {
- general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
-
- } else {
- general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
- }
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
code = nullptr;
compile(p_pattern);
}
RegEx::~RegEx() {
- if (sizeof(CharType) == 2) {
- if (code) {
- pcre2_code_free_16((pcre2_code_16 *)code);
- }
- pcre2_general_context_free_16((pcre2_general_context_16 *)general_ctx);
-
- } else {
- if (code) {
- pcre2_code_free_32((pcre2_code_32 *)code);
- }
- pcre2_general_context_free_32((pcre2_general_context_32 *)general_ctx);
+ if (code) {
+ pcre2_code_free_32((pcre2_code_32 *)code);
}
+ pcre2_general_context_free_32((pcre2_general_context_32 *)general_ctx);
}
void RegEx::_bind_methods() {
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 3aceaf11c5..346833ab9c 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -158,14 +158,16 @@ void AudioStreamOGGVorbis::clear_data() {
void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
int src_data_len = p_data.size();
-#define MAX_TEST_MEM (1 << 20)
-
uint32_t alloc_try = 1024;
Vector<char> alloc_mem;
char *w;
stb_vorbis *ogg_stream = nullptr;
stb_vorbis_alloc ogg_alloc;
+ // Vorbis comments may be up to UINT32_MAX, but that's arguably pretty rare.
+ // Let's go with 2^30 so we don't risk going out of bounds.
+ const uint32_t MAX_TEST_MEM = 1 << 30;
+
while (alloc_try < MAX_TEST_MEM) {
alloc_mem.resize(alloc_try);
w = alloc_mem.ptrw();
@@ -205,6 +207,8 @@ void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
break;
}
}
+
+ ERR_FAIL_COND_MSG(alloc_try == MAX_TEST_MEM, vformat("Couldn't set vorbis data even with an alloc buffer of %d bytes, report bug.", MAX_TEST_MEM));
}
Vector<uint8_t> AudioStreamOGGVorbis::get_data() const {
diff --git a/modules/theora/doc_classes/VideoStreamTheora.xml b/modules/theora/doc_classes/VideoStreamTheora.xml
index 92244a4d28..cb8852d5ef 100644
--- a/modules/theora/doc_classes/VideoStreamTheora.xml
+++ b/modules/theora/doc_classes/VideoStreamTheora.xml
@@ -4,7 +4,8 @@
[VideoStream] resource for Ogg Theora videos.
</brief_description>
<description>
- [VideoStream] resource handling the [url=https://www.theora.org/]Ogg Theora[/url] video format with [code].ogv[/code] extension.
+ [VideoStream] resource handling the [url=https://www.theora.org/]Ogg Theora[/url] video format with [code].ogv[/code] extension. The Theora codec is less efficient than [VideoStreamWebm]'s VP8 and VP9, but it requires less CPU resources to decode. The Theora codec is decoded on the CPU.
+ [b]Note:[/b] While Ogg Theora videos can also have an [code].ogg[/code] extension, you will have to rename the extension to [code].ogv[/code] to use those videos within Godot.
</description>
<tutorials>
</tutorials>
@@ -22,7 +23,7 @@
<argument index="0" name="file" type="String">
</argument>
<description>
- Sets the Ogg Theora video file that this [VideoStreamTheora] resource handles. The [code]file[/code] name should have the [code].o[/code] extension.
+ Sets the Ogg Theora video file that this [VideoStreamTheora] resource handles. The [code]file[/code] name should have the [code].ogv[/code] extension.
</description>
</method>
</methods>
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 9e7266b95a..5bdcb84244 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -73,8 +73,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
// Read HALF channel as FLOAT. (GH-13490)
+ bool use_float16 = false;
for (int i = 0; i < exr_header.num_channels; i++) {
if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ use_float16 = true;
exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
}
}
@@ -102,33 +104,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
idxB = c;
} else if (strcmp(exr_header.channels[c].name, "A") == 0) {
idxA = c;
- }
- }
-
- if (exr_header.num_channels == 1) {
- // Grayscale channel only.
- idxR = 0;
- idxG = 0;
- idxB = 0;
- idxA = 0;
- } else {
- // Assume RGB(A)
- if (idxR == -1) {
- ERR_PRINT("TinyEXR: R channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
- }
-
- if (idxG == -1) {
- ERR_PRINT("TinyEXR: G channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
- }
-
- if (idxB == -1) {
- ERR_PRINT("TinyEXR: B channel not found.");
- // @todo { free exr_image }
- return ERR_FILE_CORRUPT;
+ } else if (strcmp(exr_header.channels[c].name, "Y") == 0) {
+ idxR = c;
+ idxG = c;
+ idxB = c;
}
}
@@ -138,14 +117,27 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
Image::Format format;
int output_channels = 0;
+ int channel_size = use_float16 ? 2 : 4;
if (idxA != -1) {
- imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
- format = Image::FORMAT_RGBAH;
+ imgdata.resize(exr_image.width * exr_image.height * 4 * channel_size); //RGBA
+ format = use_float16 ? Image::FORMAT_RGBAH : Image::FORMAT_RGBAF;
output_channels = 4;
- } else {
- imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16
- format = Image::FORMAT_RGBH;
+ } else if (idxB != -1) {
+ ERR_FAIL_COND_V(idxG == -1, ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 3 * channel_size); //RGB
+ format = use_float16 ? Image::FORMAT_RGBH : Image::FORMAT_RGBF;
output_channels = 3;
+ } else if (idxG != -1) {
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 2 * channel_size); //RG
+ format = use_float16 ? Image::FORMAT_RGH : Image::FORMAT_RGF;
+ output_channels = 2;
+ } else {
+ ERR_FAIL_COND_V(idxR == -1, ERR_FILE_CORRUPT);
+ imgdata.resize(exr_image.width * exr_image.height * 1 * channel_size); //R
+ format = use_float16 ? Image::FORMAT_RH : Image::FORMAT_RF;
+ output_channels = 1;
}
EXRTile single_image_tile;
@@ -175,9 +167,11 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
exr_tiles = exr_image.tiles;
}
+ //print_line("reading format: " + Image::get_format_name(format));
{
uint8_t *wd = imgdata.ptrw();
- uint16_t *iw = (uint16_t *)wd;
+ uint16_t *iw16 = (uint16_t *)wd;
+ float *iw32 = (float *)wd;
// Assume `out_rgba` have enough memory allocated.
for (int tile_index = 0; tile_index < num_tiles; tile_index++) {
@@ -187,41 +181,99 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
int th = tile.height;
const float *r_channel_start = reinterpret_cast<const float *>(tile.images[idxR]);
- const float *g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]);
- const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
+ const float *g_channel_start = nullptr;
+ const float *b_channel_start = nullptr;
const float *a_channel_start = nullptr;
+ if (idxG != -1) {
+ g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]);
+ }
+ if (idxB != -1) {
+ b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
+ }
if (idxA != -1) {
a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
}
- uint16_t *first_row_w = iw + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
+ uint16_t *first_row_w16 = iw16 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
+ float *first_row_w32 = iw32 + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
for (int y = 0; y < th; y++) {
const float *r_channel = r_channel_start + y * tile_width;
- const float *g_channel = g_channel_start + y * tile_width;
- const float *b_channel = b_channel_start + y * tile_width;
+ const float *g_channel = nullptr;
+ const float *b_channel = nullptr;
const float *a_channel = nullptr;
-
+ if (g_channel_start) {
+ g_channel = g_channel_start + y * tile_width;
+ }
+ if (b_channel_start) {
+ b_channel = b_channel_start + y * tile_width;
+ }
if (a_channel_start) {
a_channel = a_channel_start + y * tile_width;
}
- uint16_t *row_w = first_row_w + (y * exr_image.width * output_channels);
-
- for (int x = 0; x < tw; x++) {
- Color color(*r_channel++, *g_channel++, *b_channel++);
-
- if (p_force_linear) {
- color = color.to_linear();
+ if (use_float16) {
+ uint16_t *row_w = first_row_w16 + (y * exr_image.width * output_channels);
+
+ for (int x = 0; x < tw; x++) {
+ Color color;
+ color.r = *r_channel++;
+ if (g_channel) {
+ color.g = *g_channel++;
+ }
+ if (b_channel) {
+ color.b = *b_channel++;
+ }
+ if (a_channel) {
+ color.a = *a_channel++;
+ }
+
+ if (p_force_linear) {
+ color = color.to_linear();
+ }
+
+ *row_w++ = Math::make_half_float(color.r);
+ if (g_channel) {
+ *row_w++ = Math::make_half_float(color.g);
+ }
+ if (b_channel) {
+ *row_w++ = Math::make_half_float(color.b);
+ }
+ if (a_channel) {
+ *row_w++ = Math::make_half_float(color.a);
+ }
}
-
- *row_w++ = Math::make_half_float(color.r);
- *row_w++ = Math::make_half_float(color.g);
- *row_w++ = Math::make_half_float(color.b);
-
- if (idxA != -1) {
- *row_w++ = Math::make_half_float(*a_channel++);
+ } else {
+ float *row_w = first_row_w32 + (y * exr_image.width * output_channels);
+
+ for (int x = 0; x < tw; x++) {
+ Color color;
+ color.r = *r_channel++;
+ if (g_channel) {
+ color.g = *g_channel++;
+ }
+ if (b_channel) {
+ color.b = *b_channel++;
+ }
+ if (a_channel) {
+ color.a = *a_channel++;
+ }
+
+ if (p_force_linear) {
+ color = color.to_linear();
+ }
+
+ *row_w++ = color.r;
+ if (g_channel) {
+ *row_w++ = color.g;
+ }
+ if (b_channel) {
+ *row_w++ = color.b;
+ }
+ if (a_channel) {
+ *row_w++ = color.a;
+ }
}
}
}
diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml
index db1ef2adc6..088d84d2ec 100644
--- a/modules/visual_script/doc_classes/VisualScript.xml
+++ b/modules/visual_script/doc_classes/VisualScript.xml
@@ -9,7 +9,7 @@
You are most likely to use this class via the Visual Script editor or when writing plugins for it.
</description>
<tutorials>
- <link>https://docs.godotengine.org/en/latest/getting_started/scripting/visual_script/index.html</link>
+ <link title="VisualScript tutorial index">https://docs.godotengine.org/en/latest/getting_started/scripting/visual_script/index.html</link>
</tutorials>
<methods>
<method name="add_custom_signal">
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index a0dcd76d10..177f9192b8 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1060,7 +1060,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::TEXT_CHAR: {
- CharType result[2] = { *p_inputs[0], 0 };
+ char32_t result[2] = { *p_inputs[0], 0 };
*r_return = String(result);
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 5581ea9318..b1d8c05d87 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1124,8 +1124,8 @@ void VisualScriptEditor::_update_members() {
TreeItem *ti = members->create_item(variables);
ti->set_text(0, E->get());
- Variant var = script->get_variable_default_value(E->get());
- ti->set_suffix(0, "= " + String(var));
+
+ ti->set_suffix(0, "= " + _sanitized_variant_text(E->get()));
ti->set_icon(0, type_icons[script->get_variable_info(E->get()).type]);
ti->set_selectable(0, true);
@@ -1167,6 +1167,18 @@ void VisualScriptEditor::_update_members() {
updating_members = false;
}
+String VisualScriptEditor::_sanitized_variant_text(const StringName &property_name) {
+ Variant var = script->get_variable_default_value(property_name);
+
+ if (script->get_variable_info(property_name).type != Variant::NIL) {
+ Callable::CallError ce;
+ const Variant *converted = &var;
+ var = Variant::construct(script->get_variable_info(property_name).type, &converted, 1, ce, false);
+ }
+
+ return String(var);
+}
+
void VisualScriptEditor::_member_selected() {
if (updating_members) {
return;
@@ -2682,7 +2694,8 @@ void VisualScriptEditor::reload(bool p_soft) {
_update_graph();
}
-void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
+Array VisualScriptEditor::get_breakpoints() {
+ Array breakpoints;
List<StringName> functions;
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
@@ -2691,10 +2704,11 @@ void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
for (List<int>::Element *F = nodes.front(); F; F = F->next()) {
Ref<VisualScriptNode> vsn = script->get_node(E->get(), F->get());
if (vsn->is_breakpoint()) {
- p_breakpoints->push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
+ breakpoints.push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
}
}
}
+ return breakpoints;
}
void VisualScriptEditor::add_callback(const String &p_function, PackedStringArray p_args) {
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 0c5665cee8..66e435741f 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -146,6 +146,7 @@ class VisualScriptEditor : public ScriptEditorBase {
bool updating_members;
void _update_members();
+ String _sanitized_variant_text(const StringName &property_name);
StringName selected;
@@ -312,7 +313,7 @@ public:
virtual void ensure_focus() override;
virtual void tag_saved_version() override;
virtual void reload(bool p_soft) override;
- virtual void get_breakpoints(List<int> *p_breakpoints) override;
+ virtual Array get_breakpoints() override;
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;
virtual bool show_members_overview() override;
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 2ac7793b8c..60a439b291 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -187,7 +187,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
- CharType cchar = GET_CHAR();
+ char32_t cchar = GET_CHAR();
if (cchar == 0) {
r_token.type = TK_EOF;
return OK;
@@ -329,7 +329,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
case '"': {
String str;
while (true) {
- CharType ch = GET_CHAR();
+ char32_t ch = GET_CHAR();
if (ch == 0) {
_set_error("Unterminated String");
@@ -340,13 +340,13 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} else if (ch == '\\') {
//escaped characters...
- CharType next = GET_CHAR();
+ char32_t next = GET_CHAR();
if (next == 0) {
_set_error("Unterminated String");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -367,7 +367,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
- CharType c = GET_CHAR();
+ char32_t c = GET_CHAR();
if (c == 0) {
_set_error("Unterminated String");
@@ -379,7 +379,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
- CharType v;
+ char32_t v;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
@@ -431,7 +431,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
#define READING_DONE 4
int reading = READING_INT;
- CharType c = cchar;
+ char32_t c = cchar;
bool exp_sign = false;
bool exp_beg = false;
bool is_float = false;
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 87aa64211e..1b77ed3168 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -933,36 +933,36 @@ static const char *op_names[] = {
};
String VisualScriptOperator::get_caption() const {
- static const wchar_t *op_names[] = {
+ static const char32_t *op_names[] = {
//comparison
- L"A = B", //OP_EQUAL,
- L"A \u2260 B", //OP_NOT_EQUAL,
- L"A < B", //OP_LESS,
- L"A \u2264 B", //OP_LESS_EQUAL,
- L"A > B", //OP_GREATER,
- L"A \u2265 B", //OP_GREATER_EQUAL,
+ U"A = B", //OP_EQUAL,
+ U"A \u2260 B", //OP_NOT_EQUAL,
+ U"A < B", //OP_LESS,
+ U"A \u2264 B", //OP_LESS_EQUAL,
+ U"A > B", //OP_GREATER,
+ U"A \u2265 B", //OP_GREATER_EQUAL,
//mathematic
- L"A + B", //OP_ADD,
- L"A - B", //OP_SUBTRACT,
- L"A \u00D7 B", //OP_MULTIPLY,
- L"A \u00F7 B", //OP_DIVIDE,
- L"\u00AC A", //OP_NEGATE,
- L"+ A", //OP_POSITIVE,
- L"A mod B", //OP_MODULE,
- L"A .. B", //OP_STRING_CONCAT,
+ U"A + B", //OP_ADD,
+ U"A - B", //OP_SUBTRACT,
+ U"A \u00D7 B", //OP_MULTIPLY,
+ U"A \u00F7 B", //OP_DIVIDE,
+ U"\u00AC A", //OP_NEGATE,
+ U"+ A", //OP_POSITIVE,
+ U"A mod B", //OP_MODULE,
+ U"A .. B", //OP_STRING_CONCAT,
//bitwise
- L"A << B", //OP_SHIFT_LEFT,
- L"A >> B", //OP_SHIFT_RIGHT,
- L"A & B", //OP_BIT_AND,
- L"A | B", //OP_BIT_OR,
- L"A ^ B", //OP_BIT_XOR,
- L"~A", //OP_BIT_NEGATE,
+ U"A << B", //OP_SHIFT_LEFT,
+ U"A >> B", //OP_SHIFT_RIGHT,
+ U"A & B", //OP_BIT_AND,
+ U"A | B", //OP_BIT_OR,
+ U"A ^ B", //OP_BIT_XOR,
+ U"~A", //OP_BIT_NEGATE,
//logic
- L"A and B", //OP_AND,
- L"A or B", //OP_OR,
- L"A xor B", //OP_XOR,
- L"not A", //OP_NOT,
- L"A in B", //OP_IN,
+ U"A and B", //OP_AND,
+ U"A or B", //OP_OR,
+ U"A xor B", //OP_XOR,
+ U"not A", //OP_NOT,
+ U"A in B", //OP_IN,
};
return op_names[op];
diff --git a/modules/webm/doc_classes/VideoStreamWebm.xml b/modules/webm/doc_classes/VideoStreamWebm.xml
index dfa04720cf..2edbc08cc8 100644
--- a/modules/webm/doc_classes/VideoStreamWebm.xml
+++ b/modules/webm/doc_classes/VideoStreamWebm.xml
@@ -4,7 +4,8 @@
[VideoStream] resource for WebM videos.
</brief_description>
<description>
- [VideoStream] resource handling the [url=https://www.webmproject.org/]WebM[/url] video format with [code].webm[/code] extension.
+ [VideoStream] resource handling the [url=https://www.webmproject.org/]WebM[/url] video format with [code].webm[/code] extension. Both the VP8 and VP9 codecs are supported. The VP8 and VP9 codecs are more efficient than [VideoStreamTheora], but they require more CPU resources to decode (especially VP9). Both the VP8 and VP9 codecs are decoded on the CPU.
+ [b]Note:[/b] There are known bugs and performance issues with WebM video playback in Godot. If you run into problems, try using the Ogg Theora format instead: [VideoStreamTheora]
</description>
<tutorials>
</tutorials>
diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
index 2054276655..c80b903e39 100644
--- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
+++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -97,7 +97,7 @@
{
"urls": [ "turn:turn.example.com:3478" ], # One or more TURN servers.
"username": "a_username", # Optional username for the TURN server.
- "credentials": "a_password", # Optional password for the TURN server.
+ "credential": "a_password", # Optional password for the TURN server.
}
]
}
diff --git a/modules/webrtc/webrtc_data_channel_gdnative.h b/modules/webrtc/webrtc_data_channel_gdnative.h
index b578802250..03396d207d 100644
--- a/modules/webrtc/webrtc_data_channel_gdnative.h
+++ b/modules/webrtc/webrtc_data_channel_gdnative.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef WEBRTC_GDNATIVE_ENABLED
-
#ifndef WEBRTC_DATA_CHANNEL_GDNATIVE_H
#define WEBRTC_DATA_CHANNEL_GDNATIVE_H
+#ifdef WEBRTC_GDNATIVE_ENABLED
+
#include "modules/gdnative/include/net/godot_net.h"
#include "webrtc_data_channel.h"
@@ -75,6 +75,6 @@ public:
~WebRTCDataChannelGDNative();
};
-#endif // WEBRTC_DATA_CHANNEL_GDNATIVE_H
-
#endif // WEBRTC_GDNATIVE_ENABLED
+
+#endif // WEBRTC_DATA_CHANNEL_GDNATIVE_H
diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h
index 455866cbf1..7545910e66 100644
--- a/modules/webrtc/webrtc_data_channel_js.h
+++ b/modules/webrtc/webrtc_data_channel_js.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef JAVASCRIPT_ENABLED
-
#ifndef WEBRTC_DATA_CHANNEL_JS_H
#define WEBRTC_DATA_CHANNEL_JS_H
+#ifdef JAVASCRIPT_ENABLED
+
#include "webrtc_data_channel.h"
class WebRTCDataChannelJS : public WebRTCDataChannel {
@@ -88,6 +88,6 @@ public:
~WebRTCDataChannelJS();
};
-#endif // WEBRTC_DATA_CHANNEL_JS_H
-
#endif // JAVASCRIPT_ENABLED
+
+#endif // WEBRTC_DATA_CHANNEL_JS_H
diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer.h
index bfdcf6daa1..fb37bd7722 100644
--- a/modules/webrtc/webrtc_multiplayer.h
+++ b/modules/webrtc/webrtc_multiplayer.h
@@ -112,4 +112,4 @@ public:
ConnectionStatus get_connection_status() const override;
};
-#endif
+#endif // WEBRTC_MULTIPLAYER_H
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.h b/modules/webrtc/webrtc_peer_connection_gdnative.h
index 74b7db1307..846b65c466 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.h
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef WEBRTC_GDNATIVE_ENABLED
-
#ifndef WEBRTC_PEER_CONNECTION_GDNATIVE_H
#define WEBRTC_PEER_CONNECTION_GDNATIVE_H
+#ifdef WEBRTC_GDNATIVE_ENABLED
+
#include "modules/gdnative/include/net/godot_net.h"
#include "webrtc_peer_connection.h"
@@ -68,6 +68,6 @@ public:
~WebRTCPeerConnectionGDNative();
};
-#endif // WEBRTC_PEER_CONNECTION_GDNATIVE_H
-
#endif // WEBRTC_GDNATIVE_ENABLED
+
+#endif // WEBRTC_PEER_CONNECTION_GDNATIVE_H
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 95b778caf6..9a144c0a78 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -453,7 +453,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String name;
bool first = true;
for (int i = 0; i < basename.length(); i++) {
- CharType c = basename[i];
+ char32_t c = basename[i];
if (c >= '0' && c <= '9' && first) {
continue;
}
@@ -484,7 +484,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
int segments = 0;
bool first = true;
for (int i = 0; i < pname.length(); i++) {
- CharType c = pname[i];
+ char32_t c = pname[i];
if (first && c == '.') {
if (r_error) {
*r_error = TTR("Package segments must be of non-zero length.");
@@ -723,7 +723,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return OK;
}
- static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+ static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
APKExportData *ed = (APKExportData *)p_userdata;
String dst_path = p_path.replace_first("res://", "assets/");
@@ -731,7 +731,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return OK;
}
- static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+ static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
return OK;
}
@@ -873,7 +873,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
if (string_flags & UTF8_FLAG) {
} else {
uint32_t len = decode_uint16(&p_manifest[string_at]);
- Vector<CharType> ucstring;
+ Vector<char32_t> ucstring;
ucstring.resize(len + 1);
for (uint32_t j = 0; j < len; j++) {
uint16_t c = decode_uint16(&p_manifest[string_at + 2 + 2 * j]);
@@ -1334,7 +1334,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
} else {
String str;
for (uint32_t i = 0; i < len; i++) {
- CharType c = decode_uint16(&p_bytes[offset + i * 2]);
+ char32_t c = decode_uint16(&p_bytes[offset + i * 2]);
if (c == 0) {
break;
}
@@ -1525,7 +1525,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
public:
- typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
+ typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key);
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override {
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 209a664f8f..95f870bc35 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -99,7 +99,7 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
// It is used by the export_project_files method to save all the asset files into the gradle project.
// It's functionality mirrors that of the method save_apk_file.
// This method will be called ONLY when custom build is enabled.
-Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
String dst_path = p_path.replace_first("res://", "res://android/build/assets/");
Error err = store_file_at_path(dst_path, p_data);
return err;
diff --git a/platform/android/java/lib/res/values/dimens.xml b/platform/android/java/lib/res/values/dimens.xml
new file mode 100644
index 0000000000..9034dbbcc1
--- /dev/null
+++ b/platform/android/java/lib/res/values/dimens.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="text_edit_height">48dp</dimen>
+</resources>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 138c2de94c..5aa48d87da 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -34,6 +34,8 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
/**
@@ -43,13 +45,18 @@ import androidx.fragment.app.FragmentActivity;
* within an Android app.
*/
public abstract class FullScreenGodotApp extends FragmentActivity {
- protected Godot godotFragment;
+ @Nullable
+ private Godot godotFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.godot_app_layout);
- godotFragment = new Godot();
+ godotFragment = initGodotInstance();
+ if (godotFragment == null) {
+ throw new IllegalStateException("Godot instance must be non-null.");
+ }
+
getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss();
}
@@ -76,4 +83,17 @@ public abstract class FullScreenGodotApp extends FragmentActivity {
}
return super.onKeyMultiple(inKeyCode, repeatCount, event);
}
+
+ /**
+ * Used to initialize the Godot fragment instance in {@link FullScreenGodotApp#onCreate(Bundle)}.
+ */
+ @NonNull
+ protected Godot initGodotInstance() {
+ return new Godot();
+ }
+
+ @Nullable
+ protected final Godot getGodotFragment() {
+ return godotFragment;
+ }
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 1b55090451..524f32bf5e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -151,8 +151,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private void setButtonPausedState(boolean paused) {
mStatePaused = paused;
- int stringResourceID = paused ? R.string.text_button_resume :
- R.string.text_button_pause;
+ int stringResourceID = paused ? R.string.text_button_resume : R.string.text_button_pause;
mPauseButton.setText(stringResourceID);
}
@@ -221,7 +220,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
// GodotEditText layout
GodotEditText editText = new GodotEditText(activity);
- editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
+ (int)getResources().getDimension(R.dimen.text_edit_height)));
// ...add to FrameLayout
containerLayout.addView(editText);
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index 1721da3db6..eea87cecc9 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -701,7 +701,7 @@ Error DisplayServerIPhone::native_video_play(String p_path, float p_volume, Stri
if (p_path.begins_with("res://")) {
if (PackedData::get_singleton()->has_path(p_path)) {
- printf("Unable to play %S using the native player as it resides in a .pck file\n", p_path.c_str());
+ printf("Unable to play %s using the native player as it resides in a .pck file\n", p_path.utf8().get_data());
return ERR_INVALID_PARAMETER;
} else {
p_path = p_path.replace("res:/", ProjectSettings::get_singleton()->get_resource_path());
@@ -712,7 +712,7 @@ Error DisplayServerIPhone::native_video_play(String p_path, float p_volume, Stri
memdelete(f);
- printf("Playing video: %S\n", p_path.c_str());
+ printf("Playing video: %s\n", p_path.utf8().get_data());
String file_path = ProjectSettings::get_singleton()->globalize_path(p_path);
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index a889717f20..19f7c8e482 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -115,7 +115,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
}
for (int i = 0; i < pname.length(); i++) {
- CharType c = pname[i];
+ char32_t c = pname[i];
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '.')) {
if (r_error) {
*r_error = vformat(TTR("The character '%s' is not allowed in Identifier."), String::chr(c));
@@ -160,9 +160,8 @@ public:
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
- if (driver == "GLES2") {
- r_features->push_back("etc");
- } else if (driver == "Vulkan") {
+ r_features->push_back("pvrtc");
+ if (driver == "Vulkan") {
// FIXME: Review if this is correct.
r_features->push_back("etc2");
}
@@ -1649,7 +1648,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
}
}
- String etc_error = test_etc2();
+ String etc_error = test_etc2_or_pvrtc();
if (etc_error != String()) {
valid = false;
err += etc_error;
diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/iphone/godot_view_gesture_recognizer.h
index ca3bd808d1..8d84914712 100644
--- a/platform/iphone/godot_view_gesture_recognizer.h
+++ b/platform/iphone/godot_view_gesture_recognizer.h
@@ -32,7 +32,7 @@
// emulating UIScrollView's UIScrollViewDelayedTouchesBeganGestureRecognizer.
// It catches all gestures incoming to UIView and delays them for 150ms
// (the same value used by UIScrollViewDelayedTouchesBeganGestureRecognizer)
-// If touch cancelation or end message is fired it fires delayed
+// If touch cancellation or end message is fired it fires delayed
// begin touch immediately as well as last touch signal
#import <UIKit/UIKit.h>
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index dfec5d7634..1477f92200 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -138,7 +138,7 @@ Error InAppStore::request_product_info(Dictionary p_params) {
NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease];
for (int i = 0; i < pids.size(); i++) {
- printf("******** adding %ls to product list\n", pids[i].c_str());
+ printf("******** adding %s to product list\n", pids[i].utf8().get_data());
NSString *pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease];
[array addObject:pid];
};
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index ad26d0ada3..6d7699c0c9 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -86,7 +86,7 @@ String iOS::get_rate_url(int p_app_id) const {
// ios7 for everything?
ret = templ_iOS7.replace("APP_ID", String::num(p_app_id));
- printf("returning rate url %ls\n", ret.c_str());
+ printf("returning rate url %s\n", ret.utf8().get_data());
return ret;
};
diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm
index d1a69642b1..946fd51923 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/iphone/os_iphone.mm
@@ -278,7 +278,7 @@ Error OSIPhone::shell_open(String p_uri) {
return ERR_CANT_OPEN;
}
- printf("opening url %ls\n", p_uri.c_str());
+ printf("opening url %s\n", p_uri.utf8().get_data());
// if (@available(iOS 10, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
@@ -293,7 +293,7 @@ void OSIPhone::set_user_data_dir(String p_dir) {
DirAccess *da = DirAccess::open(p_dir);
user_data_dir = da->get_current_dir();
- printf("setting data dir to %ls from %ls\n", user_data_dir.c_str(), p_dir.c_str());
+ printf("setting data dir to %s from %s\n", user_data_dir.utf8().get_data(), p_dir.utf8().get_data());
memdelete(da);
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index dcf9a46bf9..21456efde5 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -66,5 +66,5 @@ env.Zip(
zip_files,
ZIPROOT=zip_dir,
ZIPSUFFIX="${PROGSUFFIX}${ZIPSUFFIX}",
- ZIPCOMSTR="Archving $SOURCES as $TARGET",
+ ZIPCOMSTR="Archiving $SOURCES as $TARGET",
)
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index f029a91db0..c1607301d7 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -46,21 +46,21 @@ public:
static AudioDriverJavaScript *singleton;
- virtual const char *get_name() const;
+ const char *get_name() const override;
- virtual Error init();
- virtual void start();
+ Error init() override;
+ void start() override;
void resume();
- virtual float get_latency();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
+ float get_latency() override;
+ int get_mix_rate() const override;
+ SpeakerMode get_speaker_mode() const override;
+ void lock() override;
+ void unlock() override;
+ void finish() override;
void finish_async();
- virtual Error capture_start();
- virtual Error capture_stop();
+ Error capture_start() override;
+ Error capture_stop() override;
AudioDriverJavaScript();
};
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index 2fd1f45939..8dc33bdf64 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -75,7 +75,7 @@ bool DisplayServerJavaScript::check_size_force_redraw() {
if (last_width != canvas_width || last_height != canvas_height) {
last_width = canvas_width;
last_height = canvas_height;
- // Update the framebuffer size and for redraw.
+ // Update the framebuffer size for redraw.
emscripten_set_canvas_element_size(DisplayServerJavaScript::canvas_id, canvas_width, canvas_height);
return true;
}
@@ -892,15 +892,18 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
#define SET_EM_CALLBACK(target, ev, cb) \
result = emscripten_set_##ev##_callback(target, nullptr, true, &cb); \
EM_CHECK(ev)
+#define SET_EM_WINDOW_CALLBACK(ev, cb) \
+ result = emscripten_set_##ev##_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, &cb); \
+ EM_CHECK(ev)
#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
result = emscripten_set_##ev##_callback(nullptr, true, &cb); \
EM_CHECK(ev)
// These callbacks from Emscripten's html5.h suffice to access most
// JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM
// is used below.
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mousemove, mousemove_callback)
SET_EM_CALLBACK(canvas_id, mousedown, mouse_button_callback)
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mouseup, mouse_button_callback)
+ SET_EM_WINDOW_CALLBACK(mousemove, mousemove_callback)
+ SET_EM_WINDOW_CALLBACK(mouseup, mouse_button_callback)
SET_EM_CALLBACK(canvas_id, wheel, wheel_callback)
SET_EM_CALLBACK(canvas_id, touchstart, touch_press_callback)
SET_EM_CALLBACK(canvas_id, touchmove, touchmove_callback)
@@ -918,27 +921,25 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
/* clang-format off */
EM_ASM_ARGS({
- Module.listeners = {};
+ // Bind native event listeners.
+ // Module.listeners, and Module.drop_handler are defined in native/utils.js
const canvas = Module['canvas'];
const send_window_event = cwrap('send_window_event', null, ['number']);
const notifications = arguments;
(['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) {
- Module.listeners[event] = send_window_event.bind(null, notifications[index]);
- canvas.addEventListener(event, Module.listeners[event]);
+ Module.listeners.add(canvas, event, send_window_event.bind(null, notifications[index]), true);
});
// Clipboard
const update_clipboard = cwrap('update_clipboard', null, ['string']);
- Module.listeners['paste'] = function(evt) {
+ Module.listeners.add(window, 'paste', function(evt) {
update_clipboard(evt.clipboardData.getData('text'));
- };
- window.addEventListener('paste', Module.listeners['paste'], false);
- Module.listeners['dragover'] = function(ev) {
+ }, false);
+ // Drag an drop
+ Module.listeners.add(canvas, 'dragover', function(ev) {
// Prevent default behavior (which would try to open the file(s))
ev.preventDefault();
- };
- Module.listeners['drop'] = Module.drop_handler; // Defined in native/utils.js
- canvas.addEventListener('dragover', Module.listeners['dragover'], false);
- canvas.addEventListener('drop', Module.listeners['drop'], false);
+ }, false);
+ Module.listeners.add(canvas, 'drop', Module.drop_handler, false);
},
WINDOW_EVENT_MOUSE_ENTER,
WINDOW_EVENT_MOUSE_EXIT,
@@ -952,14 +953,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
DisplayServerJavaScript::~DisplayServerJavaScript() {
EM_ASM({
- Object.entries(Module.listeners).forEach(function(kv) {
- if (kv[0] == 'paste') {
- window.removeEventListener(kv[0], kv[1], true);
- } else {
- Module['canvas'].removeEventListener(kv[0], kv[1]);
- }
- });
- Module.listeners = {};
+ Module.listeners.clear();
});
//emscripten_webgl_commit_frame();
//emscripten_webgl_destroy_context(webgl_ctx);
@@ -1109,7 +1103,11 @@ Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const {
void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) {
last_width = p_size.x;
last_height = p_size.y;
- emscripten_set_canvas_element_size(canvas_id, p_size.x, p_size.y);
+ double scale = EM_ASM_DOUBLE({
+ return window.devicePixelRatio || 1;
+ });
+ emscripten_set_canvas_element_size(canvas_id, p_size.x * scale, p_size.y * scale);
+ emscripten_set_element_css_size(canvas_id, p_size.x, p_size.y);
}
Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const {
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 6569ef1e42..d7116be36f 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -93,7 +93,7 @@ class DisplayServerJavaScript : public DisplayServer {
static void _dispatch_input_event(const Ref<InputEvent> &p_event);
protected:
- virtual int get_current_video_driver() const;
+ int get_current_video_driver() const;
public:
// Override return type to make writing static callbacks less tedious.
@@ -113,92 +113,92 @@ public:
bool check_size_force_redraw();
// from DisplayServer
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- virtual bool has_feature(Feature p_feature) const;
- virtual String get_name() const;
+ void alert(const String &p_alert, const String &p_title = "ALERT!") override;
+ bool has_feature(Feature p_feature) const override;
+ String get_name() const override;
// cursor
- virtual void cursor_set_shape(CursorShape p_shape);
- virtual CursorShape cursor_get_shape() const;
- virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
+ void cursor_set_shape(CursorShape p_shape) override;
+ CursorShape cursor_get_shape() const override;
+ void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
// mouse
- virtual void mouse_set_mode(MouseMode p_mode);
- virtual MouseMode mouse_get_mode() const;
+ void mouse_set_mode(MouseMode p_mode) override;
+ MouseMode mouse_get_mode() const override;
// touch
- virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
// clipboard
- virtual void clipboard_set(const String &p_text);
- virtual String clipboard_get() const;
+ void clipboard_set(const String &p_text) override;
+ String clipboard_get() const override;
// screen
- virtual int get_screen_count() const;
- virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ int get_screen_count() const override;
+ Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
// windows
- virtual Vector<DisplayServer::WindowID> get_window_list() const;
- virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
+ Vector<DisplayServer::WindowID> get_window_list() const override;
+ WindowID get_window_at_screen_position(const Point2i &p_position) const override;
- virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID);
- virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
+ void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
+ ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+ void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
+ int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
+ void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID);
+ Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override;
+ void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_transient(WindowID p_window, WindowID p_parent);
+ void window_set_transient(WindowID p_window, WindowID p_parent) override;
- virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const; // FIXME: Find clearer name for this.
+ void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override;
+ Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID);
- virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const;
+ void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const;
+ bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
- virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const;
+ void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
+ bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
+ void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
+ void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
- virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+ bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual bool can_any_window_draw() const;
+ bool can_any_window_draw() const override;
// events
- virtual void process_events();
+ void process_events() override;
// icon
- virtual void set_icon(const Ref<Image> &p_icon);
+ void set_icon(const Ref<Image> &p_icon) override;
// others
- virtual bool get_swap_cancel_ok();
- virtual void swap_buffers();
+ bool get_swap_cancel_ok() override;
+ void swap_buffers() override;
static void register_javascript_driver();
DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
diff --git a/platform/javascript/engine/engine.js b/platform/javascript/engine/engine.js
index d709422abb..adcd919a6b 100644
--- a/platform/javascript/engine/engine.js
+++ b/platform/javascript/engine/engine.js
@@ -33,6 +33,7 @@ Function('return this')()['Engine'] = (function() {
this.resizeCanvasOnStart = false;
this.onExecute = null;
this.onExit = null;
+ this.persistentPaths = [];
};
Engine.prototype.init = /** @param {string=} basePath */ function(basePath) {
@@ -56,12 +57,14 @@ Function('return this')()['Engine'] = (function() {
config['locateFile'] = Utils.createLocateRewrite(loadPath);
config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
Godot(config).then(function(module) {
- me.rtenv = module;
- if (unloadAfterInit) {
- unload();
- }
- resolve();
- config = null;
+ module['initFS'](me.persistentPaths).then(function(fs_err) {
+ me.rtenv = module;
+ if (unloadAfterInit) {
+ unload();
+ }
+ resolve();
+ config = null;
+ });
});
});
return initPromise;
@@ -121,7 +124,7 @@ Function('return this')()['Engine'] = (function() {
if (me.onExit)
me.onExit(code);
me.rtenv = null;
- }
+ };
return new Promise(function(resolve, reject) {
preloader.preloadedFiles.forEach(function(file) {
me.rtenv['copyToFS'](file.path, file.buffer);
@@ -207,18 +210,22 @@ Function('return this')()['Engine'] = (function() {
if (this.rtenv)
this.rtenv.onExecute = onExecute;
this.onExecute = onExecute;
- }
+ };
Engine.prototype.setOnExit = function(onExit) {
this.onExit = onExit;
- }
+ };
Engine.prototype.copyToFS = function(path, buffer) {
if (this.rtenv == null) {
throw new Error("Engine must be inited before copying files");
}
this.rtenv['copyToFS'](path, buffer);
- }
+ };
+
+ Engine.prototype.setPersistentPaths = function(persistentPaths) {
+ this.persistentPaths = persistentPaths;
+ };
// Closure compiler exported engine methods.
/** @export */
@@ -241,5 +248,6 @@ Function('return this')()['Engine'] = (function() {
Engine.prototype['setOnExecute'] = Engine.prototype.setOnExecute;
Engine.prototype['setOnExit'] = Engine.prototype.setOnExit;
Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
+ Engine.prototype['setPersistentPaths'] = Engine.prototype.setPersistentPaths;
return Engine;
})();
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 6a3a977cfb..230575abce 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -258,6 +258,7 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
current_line = current_line.replace("$GODOT_BASENAME", p_name);
current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
+ current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false");
current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
current_line = current_line.replace("$GODOT_ARGS", flags_json);
str_export += current_line + "\n";
@@ -291,6 +292,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
}
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index a30d84a52c..01722c4bc8 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -39,6 +39,17 @@
static OS_JavaScript *os = nullptr;
static uint64_t target_ticks = 0;
+extern "C" EMSCRIPTEN_KEEPALIVE void _request_quit_callback(char *p_filev[], int p_filec) {
+ DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton();
+ if (ds) {
+ Variant event = int(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST);
+ Variant *eventp = &event;
+ Variant ret;
+ Callable::CallError ce;
+ ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce);
+ }
+}
+
void exit_callback() {
emscripten_cancel_main_loop(); // After this, we can exit!
Main::cleanup();
@@ -77,12 +88,27 @@ void main_loop_callback() {
/* clang-format on */
os->get_main_loop()->finish();
os->finalize_async(); // Will add all the async finish functions.
+ /* clang-format off */
EM_ASM({
Promise.all(Module.async_finish).then(function() {
Module.async_finish = [];
+ return new Promise(function(accept, reject) {
+ if (!Module.idbfs) {
+ accept();
+ return;
+ }
+ FS.syncfs(function(error) {
+ if (error) {
+ err('Failed to save IDB file system: ' + error.message);
+ }
+ accept();
+ });
+ });
+ }).then(function() {
ccall("cleanup_after_sync", null, []);
});
});
+ /* clang-format on */
}
}
@@ -90,31 +116,8 @@ extern "C" EMSCRIPTEN_KEEPALIVE void cleanup_after_sync() {
emscripten_set_main_loop(exit_callback, -1, false);
}
-extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
- String idbfs_err = String::utf8(p_idbfs_err);
- if (!idbfs_err.empty()) {
- print_line("IndexedDB not available: " + idbfs_err);
- }
- os->set_idb_available(idbfs_err.empty());
- // TODO: Check error return value.
- Main::setup2(); // Manual second phase.
- // Ease up compatibility.
- ResourceLoader::set_abort_on_missing_resources(false);
- Main::start();
- os->get_main_loop()->init();
- // Immediately run the first iteration.
- // We are inside an animation frame, we want to immediately draw on the newly setup canvas.
- main_loop_callback();
- emscripten_resume_main_loop();
-}
-
+/// When calling main, it is assumed FS is setup and synced.
int main(int argc, char *argv[]) {
- // Create and mount userfs immediately.
- EM_ASM({
- FS.mkdir('/userfs');
- FS.mount(IDBFS, {}, '/userfs');
- });
-
// Configure locale.
char locale_ptr[16];
/* clang-format off */
@@ -132,26 +135,30 @@ int main(int argc, char *argv[]) {
/* clang-format on */
os = new OS_JavaScript();
+ os->set_idb_available((bool)EM_ASM_INT({ return Module.idbfs }));
// We must override main when testing is enabled
TEST_MAIN_OVERRIDE
- Main::setup(argv[0], argc - 1, &argv[1], false);
- emscripten_set_main_loop(main_loop_callback, -1, false);
- emscripten_pause_main_loop(); // Will need to wait for FS sync.
+ Main::setup(argv[0], argc - 1, &argv[1]);
- // Sync from persistent state into memory and then
- // run the 'main_after_fs_sync' function.
+ // Ease up compatibility.
+ ResourceLoader::set_abort_on_missing_resources(false);
+
+ Main::start();
+ os->get_main_loop()->init();
+ // Expose method for requesting quit.
/* clang-format off */
EM_ASM({
- FS.syncfs(true, function(err) {
- requestAnimationFrame(function() {
- ccall('main_after_fs_sync', null, ['string'], [err ? err.message : ""]);
- });
- });
+ Module['request_quit'] = function() {
+ ccall("_request_quit_callback", null, []);
+ };
});
/* clang-format on */
+ emscripten_set_main_loop(main_loop_callback, -1, false);
+ // Immediately run the first iteration.
+ // We are inside an animation frame, we want to immediately draw on the newly setup canvas.
+ main_loop_callback();
return 0;
- // Continued async in main_after_fs_sync() from the syncfs() callback.
}
diff --git a/platform/javascript/native/utils.js b/platform/javascript/native/utils.js
index 95585d26ae..0b3698fd86 100644
--- a/platform/javascript/native/utils.js
+++ b/platform/javascript/native/utils.js
@@ -28,6 +28,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+Module['initFS'] = function(persistentPaths) {
+ FS.mkdir('/userfs');
+ FS.mount(IDBFS, {}, '/userfs');
+
+ function createRecursive(dir) {
+ try {
+ FS.stat(dir);
+ } catch (e) {
+ if (e.errno !== ERRNO_CODES.ENOENT) {
+ throw e;
+ }
+ FS.mkdirTree(dir);
+ }
+ }
+
+ persistentPaths.forEach(function(path) {
+ createRecursive(path);
+ FS.mount(IDBFS, {}, path);
+ });
+ return new Promise(function(resolve, reject) {
+ FS.syncfs(true, function(err) {
+ if (err) {
+ Module.idbfs = false;
+ console.log("IndexedDB not available: " + err.message);
+ } else {
+ Module.idbfs = true;
+ }
+ resolve(err);
+ });
+ });
+};
+
Module['copyToFS'] = function(path, buffer) {
var p = path.lastIndexOf("/");
var dir = "/";
@@ -37,7 +69,7 @@ Module['copyToFS'] = function(path, buffer) {
try {
FS.stat(dir);
} catch (e) {
- if (e.errno !== ERRNO_CODES.ENOENT) { // 'ENOENT', see https://github.com/emscripten-core/emscripten/blob/master/system/lib/libc/musl/arch/emscripten/bits/errno.h
+ if (e.errno !== ERRNO_CODES.ENOENT) {
throw e;
}
FS.mkdirTree(dir);
@@ -202,3 +234,44 @@ Module.drop_handler = (function() {
});
}
})();
+
+function EventHandlers() {
+ function Handler(target, event, method, capture) {
+ this.target = target;
+ this.event = event;
+ this.method = method;
+ this.capture = capture;
+ }
+
+ var listeners = [];
+
+ function has(target, event, method, capture) {
+ return listeners.findIndex(function(e) {
+ return e.target === target && e.event === event && e.method === method && e.capture == capture;
+ }) !== -1;
+ }
+
+ this.add = function(target, event, method, capture) {
+ if (has(target, event, method, capture)) {
+ return;
+ }
+ listeners.push(new Handler(target, event, method, capture));
+ target.addEventListener(event, method, capture);
+ };
+
+ this.remove = function(target, event, method, capture) {
+ if (!has(target, event, method, capture)) {
+ return;
+ }
+ target.removeEventListener(event, method, capture);
+ };
+
+ this.clear = function() {
+ listeners.forEach(function(h) {
+ h.target.removeEventListener(h.event, h.method, h.capture);
+ });
+ listeners.length = 0;
+ };
+}
+
+Module.listeners = new EventHandlers();
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 1ff4304bcf..cf5751f384 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -46,24 +46,6 @@
#include <emscripten.h>
#include <stdlib.h>
-bool OS_JavaScript::has_touchscreen_ui_hint() const {
- /* clang-format off */
- return EM_ASM_INT_V(
- return 'ontouchstart' in window;
- );
- /* clang-format on */
-}
-
-// Audio
-
-int OS_JavaScript::get_audio_driver_count() const {
- return 1;
-}
-
-const char *OS_JavaScript::get_audio_driver_name(int p_driver) const {
- return "JavaScript";
-}
-
// Lifecycle
void OS_JavaScript::initialize() {
OS_Unix::initialize_core();
@@ -90,27 +72,24 @@ MainLoop *OS_JavaScript::get_main_loop() const {
return main_loop;
}
-void OS_JavaScript::main_loop_callback() {
- get_singleton()->main_loop_iterate();
+extern "C" EMSCRIPTEN_KEEPALIVE void _idb_synced() {
+ OS_JavaScript::get_singleton()->idb_is_syncing = false;
}
bool OS_JavaScript::main_loop_iterate() {
- if (is_userfs_persistent() && sync_wait_time >= 0) {
- int64_t current_time = get_ticks_msec();
- int64_t elapsed_time = current_time - last_sync_check_time;
- last_sync_check_time = current_time;
-
- sync_wait_time -= elapsed_time;
-
- if (sync_wait_time < 0) {
- /* clang-format off */
- EM_ASM(
- FS.syncfs(function(error) {
- if (error) { err('Failed to save IDB file system: ' + error.message); }
- });
- );
- /* clang-format on */
- }
+ if (is_userfs_persistent() && idb_needs_sync && !idb_is_syncing) {
+ idb_is_syncing = true;
+ idb_needs_sync = false;
+ /* clang-format off */
+ EM_ASM({
+ FS.syncfs(function(error) {
+ if (error) {
+ err('Failed to save IDB file system: ' + error.message);
+ }
+ ccall("_idb_synced", 'void', [], []);
+ });
+ });
+ /* clang-format on */
}
DisplayServer::get_singleton()->process_events();
@@ -201,10 +180,6 @@ String OS_JavaScript::get_name() const {
return "HTML5";
}
-bool OS_JavaScript::can_draw() const {
- return true; // Always?
-}
-
String OS_JavaScript::get_user_data_dir() const {
return "/userfs";
};
@@ -222,11 +197,17 @@ String OS_JavaScript::get_data_path() const {
}
void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) {
- OS_JavaScript *os = get_singleton();
- if (os->is_userfs_persistent() && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) {
- os->last_sync_check_time = OS::get_singleton()->get_ticks_msec();
- // Wait five seconds in case more files are about to be closed.
- os->sync_wait_time = 5000;
+ OS_JavaScript *os = OS_JavaScript::get_singleton();
+ if (!(os->is_userfs_persistent() && (p_flags & FileAccess::WRITE))) {
+ return; // FS persistence is not working or we are not writing.
+ }
+ bool is_file_persistent = p_file.begins_with("/userfs");
+#ifdef TOOLS_ENABLED
+ // Hack for editor persistence (can we track).
+ is_file_persistent = is_file_persistent || p_file.begins_with("/home/web_user/");
+#endif
+ if (is_file_persistent) {
+ os->idb_needs_sync = true;
}
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 22234f9355..85551d708b 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -44,57 +44,52 @@ class OS_JavaScript : public OS_Unix {
bool finalizing = false;
bool idb_available = false;
- int64_t sync_wait_time = -1;
- int64_t last_sync_check_time = -1;
+ bool idb_needs_sync = false;
static void main_loop_callback();
static void file_access_close_callback(const String &p_file, int p_flags);
protected:
- virtual void initialize();
+ void initialize() override;
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
+ void set_main_loop(MainLoop *p_main_loop) override;
+ void delete_main_loop() override;
- virtual void finalize();
+ void finalize() override;
- virtual bool _check_internal_feature_support(const String &p_feature);
+ bool _check_internal_feature_support(const String &p_feature) override;
public:
+ bool idb_is_syncing = false;
+
// Override return type to make writing static callbacks less tedious.
static OS_JavaScript *get_singleton();
- virtual void initialize_joypads();
-
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
+ void initialize_joypads() override;
- virtual MainLoop *get_main_loop() const;
+ MainLoop *get_main_loop() const override;
void finalize_async();
bool main_loop_iterate();
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
- virtual Error kill(const ProcessID &p_pid);
- virtual int get_process_id() const;
+ Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ Error kill(const ProcessID &p_pid) override;
+ int get_process_id() const override;
- String get_executable_path() const;
- virtual Error shell_open(String p_uri);
- virtual String get_name() const;
+ String get_executable_path() const override;
+ Error shell_open(String p_uri) override;
+ String get_name() const override;
// Override default OS implementation which would block the main thread with delay_usec.
// Implemented in javascript_main.cpp loop callback instead.
- virtual void add_frame_delay(bool p_can_draw) {}
- virtual bool can_draw() const;
+ void add_frame_delay(bool p_can_draw) override {}
- virtual String get_cache_path() const;
- virtual String get_config_path() const;
- virtual String get_data_path() const;
- virtual String get_user_data_dir() const;
+ String get_cache_path() const override;
+ String get_config_path() const override;
+ String get_data_path() const override;
+ String get_user_data_dir() const override;
void set_idb_available(bool p_idb_available);
- virtual bool is_userfs_persistent() const;
+ bool is_userfs_persistent() const override;
void resume_audio();
bool is_finalizing() { return finalizing; }
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index b3553e961a..e2b88b7704 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -67,7 +67,7 @@ static void handle_crash(int sig) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
}
- fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
for (size_t i = 1; i < size; i++) {
@@ -109,7 +109,7 @@ static void handle_crash(int sig) {
output.erase(output.length() - 1, 1);
}
- fprintf(stderr, "[%ld] %s (%ls)\n", (long int)i, fname, output.c_str());
+ fprintf(stderr, "[%ld] %s (%s)\n", (long int)i, fname, output.utf8().get_data());
}
free(strings);
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 3eb4c44bc1..f5e2c72bbc 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -35,6 +35,11 @@ def can_build():
print("xinerama not found.. x11 disabled.")
return False
+ x11_error = os.system("pkg-config xext --modversion > /dev/null ")
+ if x11_error:
+ print("xext not found.. x11 disabled.")
+ return False
+
x11_error = os.system("pkg-config xrandr --modversion > /dev/null ")
if x11_error:
print("xrandr not found.. x11 disabled.")
@@ -194,6 +199,7 @@ def configure(env):
env.ParseConfig("pkg-config x11 --cflags --libs")
env.ParseConfig("pkg-config xcursor --cflags --libs")
env.ParseConfig("pkg-config xinerama --cflags --libs")
+ env.ParseConfig("pkg-config xext --cflags --libs")
env.ParseConfig("pkg-config xrandr --cflags --libs")
env.ParseConfig("pkg-config xrender --cflags --libs")
env.ParseConfig("pkg-config xi --cflags --libs")
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index a0aced26ab..e3cf992302 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -50,6 +50,7 @@
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xinerama.h>
+#include <X11/extensions/shape.h>
// ICCCM
#define WM_NormalState 1L // window normal state
@@ -83,6 +84,13 @@
#define VALUATOR_TILTX 3
#define VALUATOR_TILTY 4
+//#define DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
+#ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
+#define DEBUG_LOG_X11(...) printf(__VA_ARGS__)
+#else
+#define DEBUG_LOG_X11(...)
+#endif
+
static const double abs_resolution_mult = 10000.0;
static const double abs_resolution_range_mult = 10.0;
@@ -681,6 +689,14 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, u
return id;
}
+void DisplayServerX11::show_window(WindowID p_id) {
+ _THREAD_SAFE_METHOD_
+
+ WindowData &wd = windows[p_id];
+
+ XMapWindow(x11_display, wd.x11_window);
+}
+
void DisplayServerX11::delete_sub_window(WindowID p_id) {
_THREAD_SAFE_METHOD_
@@ -689,6 +705,8 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
WindowData &wd = windows[p_id];
+ DEBUG_LOG_X11("delete_sub_window: %lu (%u) \n", wd.x11_window, p_id);
+
while (wd.transient_children.size()) {
window_set_transient(wd.transient_children.front()->get(), INVALID_WINDOW_ID);
}
@@ -725,15 +743,31 @@ ObjectID DisplayServerX11::window_get_attached_instance_id(WindowID p_window) co
}
DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const Point2i &p_position) const {
-#warning This is an incorrect implementation, if windows overlap, it should return the topmost visible one or none if occluded by a foreign window
-
+ WindowID found_window = INVALID_WINDOW_ID;
+ WindowID parent_window = INVALID_WINDOW_ID;
+ unsigned int focus_order = 0;
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- Rect2i win_rect = Rect2i(window_get_position(E->key()), window_get_size(E->key()));
+ const WindowData &wd = E->get();
+
+ // Discard windows with no focus.
+ if (wd.focus_order == 0) {
+ continue;
+ }
+
+ // Find topmost window which contains the given position.
+ WindowID window_id = E->key();
+ Rect2i win_rect = Rect2i(window_get_position(window_id), window_get_size(window_id));
if (win_rect.has_point(p_position)) {
- return E->key();
+ // For siblings, pick the window which was focused last.
+ if ((parent_window != wd.transient_parent) || (wd.focus_order > focus_order)) {
+ found_window = window_id;
+ parent_window = wd.transient_parent;
+ focus_order = wd.focus_order;
+ }
}
}
- return INVALID_WINDOW_ID;
+
+ return found_window;
}
void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window) {
@@ -749,6 +783,38 @@ void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window
XChangeProperty(x11_display, wd.x11_window, _net_wm_name, utf8_string, 8, PropModeReplace, (unsigned char *)p_title.utf8().get_data(), p_title.utf8().length());
}
+void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ const WindowData &wd = windows[p_window];
+
+ int event_base, error_base;
+ const Bool ext_okay = XShapeQueryExtension(x11_display, &event_base, &error_base);
+ if (ext_okay) {
+ Region region;
+ if (p_region.size() == 0) {
+ region = XCreateRegion();
+ XRectangle rect;
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = window_get_real_size(p_window).x;
+ rect.height = window_get_real_size(p_window).y;
+ XUnionRectWithRegion(&rect, region, region);
+ } else {
+ XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * p_region.size());
+ for (int i = 0; i < p_region.size(); i++) {
+ points[i].x = p_region[i].x;
+ points[i].y = p_region[i].y;
+ }
+ region = XPolygonRegion(points, p_region.size(), EvenOddRule);
+ memfree(points);
+ }
+ XShapeCombineRegion(x11_display, wd.x11_window, ShapeInput, 0, 0, region, ShapeSet);
+ XDestroyRegion(region);
+ }
+}
+
void DisplayServerX11::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -842,24 +908,34 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd_window = windows[p_window];
- ERR_FAIL_COND(wd_window.transient_parent == p_parent);
+ WindowID prev_parent = wd_window.transient_parent;
+ ERR_FAIL_COND(prev_parent == p_parent);
ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient.");
if (p_parent == INVALID_WINDOW_ID) {
//remove transient
- ERR_FAIL_COND(wd_window.transient_parent == INVALID_WINDOW_ID);
- ERR_FAIL_COND(!windows.has(wd_window.transient_parent));
+ ERR_FAIL_COND(prev_parent == INVALID_WINDOW_ID);
+ ERR_FAIL_COND(!windows.has(prev_parent));
- WindowData &wd_parent = windows[wd_window.transient_parent];
+ WindowData &wd_parent = windows[prev_parent];
wd_window.transient_parent = INVALID_WINDOW_ID;
wd_parent.transient_children.erase(p_window);
XSetTransientForHint(x11_display, wd_window.x11_window, None);
+
+ // Set focus to parent sub window to avoid losing all focus with nested menus.
+ // RevertToPointerRoot is used to make sure we don't lose all focus in case
+ // a subwindow and its parent are both destroyed.
+ if (wd_window.menu_type && !wd_window.no_focus) {
+ if (!wd_parent.no_focus) {
+ XSetInputFocus(x11_display, wd_parent.x11_window, RevertToPointerRoot, CurrentTime);
+ }
+ }
} else {
ERR_FAIL_COND(!windows.has(p_parent));
- ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent");
+ ERR_FAIL_COND_MSG(prev_parent != INVALID_WINDOW_ID, "Window already has a transient parent");
WindowData &wd_parent = windows[p_parent];
wd_window.transient_parent = p_parent;
@@ -2285,6 +2361,11 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev
void DisplayServerX11::process_events() {
_THREAD_SAFE_METHOD_
+#ifdef DISPLAY_SERVER_X11_DEBUG_LOGS_ENABLED
+ static int frame = 0;
+ ++frame;
+#endif
+
if (app_focused) {
//verify that one of the windows has focus, else send focus out notification
bool focus_found = false;
@@ -2301,6 +2382,7 @@ void DisplayServerX11::process_events() {
if (delta > 250) {
//X11 can go between windows and have no focus for a while, when creating them or something else. Use this as safety to avoid unnecessary focus in/outs.
if (OS::get_singleton()->get_main_loop()) {
+ DEBUG_LOG_X11("All focus lost, triggering NOTIFICATION_APPLICATION_FOCUS_OUT\n");
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
}
app_focused = false;
@@ -2323,6 +2405,10 @@ void DisplayServerX11::process_events() {
XEvent event;
XNextEvent(x11_display, &event);
+ if (XFilterEvent(&event, None)) {
+ continue;
+ }
+
WindowID window_id = MAIN_WINDOW_ID;
// Assign the event to the relevant window
@@ -2333,10 +2419,6 @@ void DisplayServerX11::process_events() {
}
}
- if (XFilterEvent(&event, None)) {
- continue;
- }
-
if (XGetEventData(x11_display, &event.xcookie)) {
if (event.xcookie.type == GenericEvent && event.xcookie.extension == xi.opcode) {
XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
@@ -2499,32 +2581,67 @@ void DisplayServerX11::process_events() {
XFreeEventData(x11_display, &event.xcookie);
switch (event.type) {
- case Expose:
+ case MapNotify: {
+ DEBUG_LOG_X11("[%u] MapNotify window=%lu (%u) \n", frame, event.xmap.window, window_id);
+
+ const WindowData &wd = windows[window_id];
+
+ // Set focus when menu window is started.
+ // RevertToPointerRoot is used to make sure we don't lose all focus in case
+ // a subwindow and its parent are both destroyed.
+ if (wd.menu_type && !wd.no_focus) {
+ XSetInputFocus(x11_display, wd.x11_window, RevertToPointerRoot, CurrentTime);
+ }
+ } break;
+
+ case Expose: {
+ DEBUG_LOG_X11("[%u] Expose window=%lu (%u), count='%u' \n", frame, event.xexpose.window, window_id, event.xexpose.count);
+
Main::force_redraw();
- break;
+ } break;
+
+ case NoExpose: {
+ DEBUG_LOG_X11("[%u] NoExpose drawable=%lu (%u) \n", frame, event.xnoexpose.drawable, window_id);
- case NoExpose:
windows[window_id].minimized = true;
- break;
+ } break;
case VisibilityNotify: {
+ DEBUG_LOG_X11("[%u] VisibilityNotify window=%lu (%u), state=%u \n", frame, event.xvisibility.window, window_id, event.xvisibility.state);
+
XVisibilityEvent *visibility = (XVisibilityEvent *)&event;
windows[window_id].minimized = (visibility->state == VisibilityFullyObscured);
} break;
+
case LeaveNotify: {
+ DEBUG_LOG_X11("[%u] LeaveNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode);
+
if (!mouse_mode_grab) {
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
}
} break;
+
case EnterNotify: {
+ DEBUG_LOG_X11("[%u] EnterNotify window=%lu (%u), mode='%u' \n", frame, event.xcrossing.window, window_id, event.xcrossing.mode);
+
if (!mouse_mode_grab) {
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
} break;
- case FocusIn:
- windows[window_id].focused = true;
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
+
+ case FocusIn: {
+ DEBUG_LOG_X11("[%u] FocusIn window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode);
+
+ WindowData &wd = windows[window_id];
+
+ wd.focused = true;
+
+ // Keep track of focus order for overlapping windows.
+ static unsigned int focus_order = 0;
+ wd.focus_order = ++focus_order;
+
+ _send_window_event(wd, WINDOW_EVENT_FOCUS_IN);
if (mouse_mode_grab) {
// Show and update the cursor if confined and the window regained focus.
@@ -2548,8 +2665,8 @@ void DisplayServerX11::process_events() {
XIGrabDevice(x11_display, xi.touch_devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &xi.touch_event_mask);
}*/
#endif
- if (windows[window_id].xic) {
- XSetICFocus(windows[window_id].xic);
+ if (wd.xic) {
+ XSetICFocus(wd.xic);
}
if (!app_focused) {
@@ -2558,12 +2675,17 @@ void DisplayServerX11::process_events() {
}
app_focused = true;
}
- break;
+ } break;
+
+ case FocusOut: {
+ DEBUG_LOG_X11("[%u] FocusOut window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode);
+
+ WindowData &wd = windows[window_id];
+
+ wd.focused = false;
- case FocusOut:
- windows[window_id].focused = false;
Input::get_singleton()->release_pressed_events();
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
+ _send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
if (mouse_mode_grab) {
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
@@ -2592,14 +2714,26 @@ void DisplayServerX11::process_events() {
}
xi.state.clear();
#endif
- if (windows[window_id].xic) {
- XSetICFocus(windows[window_id].xic);
+ if (wd.xic) {
+ XSetICFocus(wd.xic);
+ }
+ } break;
+
+ case ConfigureNotify: {
+ DEBUG_LOG_X11("[%u] ConfigureNotify window=%lu (%u), event=%lu, above=%lu, override_redirect=%u \n", frame, event.xconfigure.window, window_id, event.xconfigure.event, event.xconfigure.above, event.xconfigure.override_redirect);
+
+ const WindowData &wd = windows[window_id];
+
+ // Set focus when menu window is re-used.
+ // RevertToPointerRoot is used to make sure we don't lose all focus in case
+ // a subwindow and its parent are both destroyed.
+ if (wd.menu_type && !wd.no_focus) {
+ XSetInputFocus(x11_display, wd.x11_window, RevertToPointerRoot, CurrentTime);
}
- break;
- case ConfigureNotify:
_window_changed(&event);
- break;
+ } break;
+
case ButtonPress:
case ButtonRelease: {
/* exit in case of a mouse button press */
@@ -2626,7 +2760,18 @@ void DisplayServerX11::process_events() {
mb->set_pressed((event.type == ButtonPress));
+ const WindowData &wd = windows[window_id];
+
if (event.type == ButtonPress) {
+ DEBUG_LOG_X11("[%u] ButtonPress window=%lu (%u), button_index=%u \n", frame, event.xbutton.window, window_id, mb->get_button_index());
+
+ // Ensure window focus on click.
+ // RevertToPointerRoot is used to make sure we don't lose all focus in case
+ // a subwindow and its parent are both destroyed.
+ if (!wd.no_focus) {
+ XSetInputFocus(x11_display, wd.x11_window, RevertToPointerRoot, CurrentTime);
+ }
+
uint64_t diff = OS::get_singleton()->get_ticks_usec() / 1000 - last_click_ms;
if (mb->get_button_index() == last_click_button_index) {
@@ -2645,6 +2790,33 @@ void DisplayServerX11::process_events() {
last_click_ms += diff;
last_click_pos = Point2i(event.xbutton.x, event.xbutton.y);
}
+ } else {
+ DEBUG_LOG_X11("[%u] ButtonRelease window=%lu (%u), button_index=%u \n", frame, event.xbutton.window, window_id, mb->get_button_index());
+
+ if (!wd.focused) {
+ // Propagate the event to the focused window,
+ // because it's received only on the topmost window.
+ // Note: This is needed for drag & drop to work between windows,
+ // because the engine expects events to keep being processed
+ // on the same window dragging started.
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ const WindowData &wd_other = E->get();
+ WindowID window_id_other = E->key();
+ if (wd_other.focused) {
+ if (window_id_other != window_id) {
+ int x, y;
+ Window child;
+ XTranslateCoordinates(x11_display, wd.x11_window, wd_other.x11_window, event.xbutton.x, event.xbutton.y, &x, &y, &child);
+
+ mb->set_window_id(window_id_other);
+ mb->set_position(Vector2(x, y));
+ mb->set_global_position(mb->get_position());
+ Input::get_singleton()->accumulate_input_event(mb);
+ }
+ break;
+ }
+ }
+ }
}
Input::get_singleton()->accumulate_input_event(mb);
@@ -2694,6 +2866,9 @@ void DisplayServerX11::process_events() {
break;
}
+ const WindowData &wd = windows[window_id];
+ bool focused = wd.focused;
+
if (mouse_mode == MOUSE_MODE_CAPTURED) {
if (xi.relative_motion.x == 0 && xi.relative_motion.y == 0) {
break;
@@ -2702,7 +2877,7 @@ void DisplayServerX11::process_events() {
Point2i new_center = pos;
pos = last_mouse_pos + xi.relative_motion;
center = new_center;
- do_mouse_warp = windows[window_id].focused; // warp the cursor if we're focused in
+ do_mouse_warp = focused; // warp the cursor if we're focused in
}
if (!last_mouse_pos_valid) {
@@ -2744,14 +2919,11 @@ void DisplayServerX11::process_events() {
}
mm->set_tilt(xi.tilt);
- // Make the absolute position integral so it doesn't look _too_ weird :)
- Point2i posi(pos);
-
_get_key_modifier_state(event.xmotion.state, mm);
mm->set_button_mask(mouse_get_button_state());
- mm->set_position(posi);
- mm->set_global_position(posi);
- Input::get_singleton()->set_mouse_position(posi);
+ mm->set_position(pos);
+ mm->set_global_position(pos);
+ Input::get_singleton()->set_mouse_position(pos);
mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
mm->set_relative(rel);
@@ -2762,8 +2934,32 @@ void DisplayServerX11::process_events() {
// Don't propagate the motion event unless we have focus
// this is so that the relative motion doesn't get messed up
// after we regain focus.
- if (windows[window_id].focused || !mouse_mode_grab) {
+ if (focused) {
Input::get_singleton()->accumulate_input_event(mm);
+ } else {
+ // Propagate the event to the focused window,
+ // because it's received only on the topmost window.
+ // Note: This is needed for drag & drop to work between windows,
+ // because the engine expects events to keep being processed
+ // on the same window dragging started.
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ const WindowData &wd_other = E->get();
+ if (wd_other.focused) {
+ int x, y;
+ Window child;
+ XTranslateCoordinates(x11_display, wd.x11_window, wd_other.x11_window, event.xmotion.x, event.xmotion.y, &x, &y, &child);
+
+ Point2i pos_focused(x, y);
+
+ mm->set_window_id(E->key());
+ mm->set_position(pos_focused);
+ mm->set_global_position(pos_focused);
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ Input::get_singleton()->accumulate_input_event(mm);
+
+ break;
+ }
+ }
}
} break;
@@ -3140,12 +3336,37 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
- WindowID id;
+ WindowID id = window_id_counter++;
+ WindowData &wd = windows[id];
+
+ if ((id != MAIN_WINDOW_ID) && (p_flags & WINDOW_FLAG_BORDERLESS_BIT)) {
+ wd.menu_type = true;
+ }
+
+ if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
+ wd.menu_type = true;
+ wd.no_focus = true;
+ }
+
+ // Setup for menu subwindows:
+ // - override_redirect forces the WM not to interfere with the window, to avoid delays due to
+ // handling decorations and placement.
+ // On the other hand, focus changes need to be handled manually when this is set.
+ // - save_under is a hint for the WM to keep the content of windows behind to avoid repaint.
+ if (wd.menu_type) {
+ windowAttributes.override_redirect = True;
+ windowAttributes.save_under = True;
+ valuemask |= CWOverrideRedirect | CWSaveUnder;
+ }
+
{
- WindowData wd;
wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), p_rect.position.x, p_rect.position.y, p_rect.size.width > 0 ? p_rect.size.width : 1, p_rect.size.height > 0 ? p_rect.size.height : 1, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
- XMapWindow(x11_display, wd.x11_window);
+ // Enable receiving notification when the window is initialized (MapNotify)
+ // so the focus can be set at the right time.
+ if (wd.menu_type && !wd.no_focus) {
+ XSelectInput(x11_display, wd.x11_window, StructureNotifyMask);
+ }
//associate PID
// make PID known to X11
@@ -3221,58 +3442,26 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
_update_context(wd);
- id = window_id_counter++;
-
- windows[id] = wd;
-
- {
- bool make_utility = false;
-
- if (p_flags & WINDOW_FLAG_BORDERLESS_BIT) {
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = 0;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, wd.x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
-
- make_utility = true;
- }
- if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
- make_utility = true;
- }
-
- if (make_utility) {
- //this one seems to disable the fade animations for regular windows
- //but has the drawback that will not get focus by default, so
- //we need to force it, unless no focus requested
-
- Atom type_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
- Atom wt_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE", False);
-
- XChangeProperty(x11_display, wd.x11_window, wt_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type_atom, 1);
-
- if (!(p_flags & WINDOW_FLAG_NO_FOCUS_BIT)) {
- //but as utility appears unfocused, it needs to be forcefuly focused, unless no focus requested
- XEvent xev;
- Atom net_active_window = XInternAtom(x11_display, "_NET_ACTIVE_WINDOW", False);
+ if (p_flags & WINDOW_FLAG_BORDERLESS_BIT) {
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = 0;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, wd.x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+ }
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = wd.x11_window;
- xev.xclient.message_type = net_active_window;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = CurrentTime;
+ if (wd.menu_type) {
+ // Set Utility type to disable fade animations.
+ Atom type_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
+ Atom wt_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE", False);
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- }
- } else {
- Atom type_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
- Atom wt_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE", False);
+ XChangeProperty(x11_display, wd.x11_window, wt_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type_atom, 1);
+ } else {
+ Atom type_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
+ Atom wt_atom = XInternAtom(x11_display, "_NET_WM_WINDOW_TYPE", False);
- XChangeProperty(x11_display, wd.x11_window, wt_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type_atom, 1);
- }
+ XChangeProperty(x11_display, wd.x11_window, wt_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&type_atom, 1);
}
_update_size_hints(id);
@@ -3293,8 +3482,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
XFree(visualInfo);
}
- WindowData &wd = windows[id];
-
window_set_mode(p_mode, id);
//sync size
@@ -3316,6 +3503,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
if (cursors[current_cursor] != None) {
XDefineCursor(x11_display, wd.x11_window, cursors[current_cursor]);
}
+
return id;
}
@@ -3387,7 +3575,12 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
xrandr_handle = dlopen("libXrandr.so.2", RTLD_LAZY);
if (!xrandr_handle) {
err = dlerror();
- fprintf(stderr, "could not load libXrandr.so.2, Error: %s\n", err);
+ // For some arcane reason, NetBSD now ships libXrandr.so.3 while the rest of the world has libXrandr.so.2...
+ // In case this happens for other X11 platforms in the future, let's give it a try too before failing.
+ xrandr_handle = dlopen("libXrandr.so.3", RTLD_LAZY);
+ if (!xrandr_handle) {
+ fprintf(stderr, "could not load libXrandr.so.2, Error: %s\n", err);
+ }
} else {
XRRQueryVersion(x11_display, &xrandr_major, &xrandr_minor);
if (((xrandr_major << 8) | xrandr_minor) >= 0x0105) {
@@ -3555,6 +3748,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
window_set_flag(WindowFlags(i), true, main_window);
}
}
+ show_window(main_window);
//create RenderingDevice if used
#if defined(VULKAN_ENABLED)
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index fb50b484a0..e894cf515c 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -132,6 +132,9 @@ class DisplayServerX11 : public DisplayServer {
ObjectID instance_id;
+ bool menu_type = false;
+ bool no_focus = false;
+
//better to guess on the fly, given WM can change it
//WindowMode mode;
bool fullscreen = false; //OS can't exit from this mode
@@ -141,6 +144,8 @@ class DisplayServerX11 : public DisplayServer {
Vector2i last_position_before_fs;
bool focused = false;
bool minimized = false;
+
+ unsigned int focus_order = 0;
};
Map<WindowID, WindowData> windows;
@@ -277,6 +282,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
@@ -285,6 +291,8 @@ public:
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID);
+
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 764666681f..571ad03db0 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -31,7 +31,15 @@
#ifdef __linux__
#include <alloca.h>
#endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <stdlib.h>
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#include <stdlib.h> // alloca
+// FreeBSD and OpenBSD use pthread_set_name_np, while other platforms,
+// include NetBSD, use pthread_setname_np. NetBSD's version however requires
+// a different format, we handle this directly in thread_posix.
+#ifdef __NetBSD__
+#define PTHREAD_NETBSD_SET_NAME
+#else
#define PTHREAD_BSD_SET_NAME
#endif
+#endif
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 5da0118686..9fb2f63935 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -90,7 +90,7 @@ static void handle_crash(int sig) {
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
- fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
void *load_addr = (void *)load_address();
@@ -142,7 +142,7 @@ static void handle_crash(int sig) {
}
}
- fprintf(stderr, "[%zu] %ls\n", i, output.c_str());
+ fprintf(stderr, "[%zu] %s\n", i, output.utf8().get_data());
}
free(strings);
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index a4a382f3a9..6fc1dc65af 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -1,6 +1,5 @@
import os
import sys
-import subprocess
from methods import detect_darwin_sdk_path
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 68e8454fd0..073d35008b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -102,6 +102,8 @@ public:
id window_object;
id window_view;
+ Vector<Vector2> mpath;
+
#if defined(OPENGL_ENABLED)
ContextGL_OSX *context_gles2 = nullptr;
#endif
@@ -230,6 +232,7 @@ public:
virtual Vector<int> get_window_list() const override;
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+ virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
@@ -239,6 +242,7 @@ public:
virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID) override;
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 1676e0d425..49f0e7bfa3 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -33,6 +33,7 @@
#include "os_osx.h"
#include "core/io/marshalls.h"
+#include "core/math/geometry_2d.h"
#include "core/os/keyboard.h"
#include "main/main.h"
#include "scene/resources/texture.h"
@@ -2040,6 +2041,12 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
CGAssociateMouseAndMouseCursorPosition(false);
+ WindowData &wd = windows[MAIN_WINDOW_ID];
+ const NSRect contentRect = [wd.window_view frame];
+ NSRect pointInWindowRect = NSMakeRect(contentRect.size.width / 2, contentRect.size.height / 2, 0, 0);
+ NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
+ CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y };
+ CGWarpMouseCursorPosition(lMouseWarpPos);
} else if (p_mode == MOUSE_MODE_HIDDEN) {
if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
CGDisplayHideCursor(kCGDirectMainDisplay);
@@ -2314,18 +2321,23 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, u
_THREAD_SAFE_METHOD_
WindowID id = _create_window(p_mode, p_rect);
- WindowData &wd = windows[id];
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
}
}
+
+ return id;
+}
+
+void DisplayServerOSX::show_window(WindowID p_id) {
+ WindowData &wd = windows[p_id];
+
if (wd.no_focus) {
[wd.window_object orderFront:nil];
} else {
[wd.window_object makeKeyAndOrderFront:nil];
}
- return id;
}
void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) {
@@ -2399,6 +2411,15 @@ void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window
[wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
}
+void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ WindowData &wd = windows[p_window];
+
+ wd.mpath = p_region;
+}
+
void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -3351,6 +3372,26 @@ void DisplayServerOSX::process_events() {
Input::get_singleton()->flush_accumulated_events();
}
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ WindowData &wd = E->get();
+ if (wd.mpath.size() > 0) {
+ const Vector2 mpos = _get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
+ if (Geometry2D::is_point_in_polygon(mpos, wd.mpath)) {
+ if ([wd.window_object ignoresMouseEvents]) {
+ [wd.window_object setIgnoresMouseEvents:NO];
+ }
+ } else {
+ if (![wd.window_object ignoresMouseEvents]) {
+ [wd.window_object setIgnoresMouseEvents:YES];
+ }
+ }
+ } else {
+ if ([wd.window_object ignoresMouseEvents]) {
+ [wd.window_object setIgnoresMouseEvents:NO];
+ }
+ }
+ }
+
[autoreleasePool drain];
autoreleasePool = [[NSAutoreleasePool alloc] init];
}
@@ -3774,7 +3815,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
window_set_flag(WindowFlags(i), true, main_window);
}
}
- [windows[main_window].window_object makeKeyAndOrderFront:nil];
+ show_window(MAIN_WINDOW_ID);
#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 0cf02ef69b..9f2160dd9e 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -78,7 +78,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
}
for (int i = 0; i < pname.length(); i++) {
- CharType c = pname[i];
+ char32_t c = pname[i];
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '.')) {
if (r_error) {
*r_error = vformat(TTR("The character '%s' is not allowed in Identifier."), String::chr(c));
diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h
index bdff93f02b..73136ec81b 100644
--- a/platform/server/platform_config.h
+++ b/platform/server/platform_config.h
@@ -31,10 +31,19 @@
#if defined(__linux__) || defined(__APPLE__)
#include <alloca.h>
#endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <stdlib.h>
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#include <stdlib.h> // alloca
+// FreeBSD and OpenBSD use pthread_set_name_np, while other platforms,
+// include NetBSD, use pthread_setname_np. NetBSD's version however requires
+// a different format, we handle this directly in thread_posix.
+#ifdef __NetBSD__
+#define PTHREAD_NETBSD_SET_NAME
+#else
#define PTHREAD_BSD_SET_NAME
#endif
+#endif
+
#ifdef __APPLE__
#define PTHREAD_RENAME_SELF
#endif
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 04b743f2c8..a7ca26c16c 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -65,12 +65,14 @@ def configure(env):
env.Append(CCFLAGS=["/MD"])
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
+ env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
elif env["target"] == "debug":
env.Append(CCFLAGS=["/Zi"])
env.Append(CCFLAGS=["/MDd"])
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
+ env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
env.Append(LINKFLAGS=["/DEBUG"])
## Compiler configuration
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index ede0d7c76b..5679ec3eac 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -961,7 +961,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
return true;
}
- static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+ static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
AppxPackager *packager = (AppxPackager *)p_userdata;
String dst_path = p_path.replace_first("res://", "game/");
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 401ba6c35d..44ab075816 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -296,7 +296,7 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
void OS_UWP::set_clipboard(const String &p_text) {
DataPackage ^ clip = ref new DataPackage();
clip->RequestedOperation = DataPackageOperation::Copy;
- clip->SetText(ref new Platform::String((const wchar_t *)p_text.c_str()));
+ clip->SetText(ref new Platform::String((LPCWSTR)(p_text.utf16().get_data())));
Clipboard::SetContent(clip);
};
@@ -346,8 +346,8 @@ void OS_UWP::finalize_core() {
}
void OS_UWP::alert(const String &p_alert, const String &p_title) {
- Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
- Platform::String ^ title = ref new Platform::String(p_title.c_str());
+ Platform::String ^ alert = ref new Platform::String((LPCWSTR)(p_alert.utf16().get_data()));
+ Platform::String ^ title = ref new Platform::String((LPCWSTR)(p_title.utf16().get_data()));
MessageDialog ^ msg = ref new MessageDialog(alert, title);
@@ -738,7 +738,7 @@ static String format_error_message(DWORD id) {
Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
String full_path = "game/" + p_path;
- p_library_handle = (void *)LoadPackagedLibrary(full_path.c_str(), 0);
+ p_library_handle = (void *)LoadPackagedLibrary((LPCWSTR)(full_path.utf16().get_data()), 0);
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;
}
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index daffe59f34..e3f86977a4 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -26,10 +26,10 @@ prog = env.add_program("#bin/godot", common_win + res_obj, PROGSUFFIX=env["PROGS
# Microsoft Visual Studio Project Generation
if env["vsproj"]:
- env.vs_srcs = env.vs_srcs + ["platform/windows/" + res_file]
- env.vs_srcs = env.vs_srcs + ["platform/windows/godot.natvis"]
+ env.vs_srcs += ["platform/windows/" + res_file]
+ env.vs_srcs += ["platform/windows/godot.natvis"]
for x in common_win:
- env.vs_srcs = env.vs_srcs + ["platform/windows/" + str(x)]
+ env.vs_srcs += ["platform/windows/" + str(x)]
if not os.getenv("VCINSTALLDIR"):
if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]:
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 996d9722f5..02031ef6bb 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -175,7 +175,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
msg = proj_settings->get("debug/settings/crash_handler/message");
}
- fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
int n = 0;
do {
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index a9f25fa078..6b503c1561 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -65,6 +65,7 @@ def get_opts():
# Vista support dropped after EOL due to GH-10243
("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"),
EnumVariable("debug_symbols", "Add debugging symbols to release builds", "yes", ("yes", "no", "full")),
+ EnumVariable("windows_subsystem", "Windows subsystem", "gui", ("console", "gui")),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None),
BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed. Only used on Windows.", False),
@@ -177,6 +178,8 @@ def configure_msvc(env, manual_msvc_config):
"""Configure env to work with MSVC"""
# Build type
+ if env["tests"]:
+ env["windows_subsystem"] = "console"
if env["target"] == "release":
if env["optimize"] == "speed": # optimize for speed (default)
@@ -199,12 +202,16 @@ def configure_msvc(env, manual_msvc_config):
env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/DEBUG"])
- env.Append(LINKFLAGS=["/SUBSYSTEM:WINDOWS"])
-
if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes":
env.AppendUnique(CCFLAGS=["/Z7"])
env.AppendUnique(LINKFLAGS=["/DEBUG"])
+ if env["windows_subsystem"] == "gui":
+ env.Append(LINKFLAGS=["/SUBSYSTEM:WINDOWS"])
+ else:
+ env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
+ env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
+
## Compile/link flags
env.AppendUnique(CCFLAGS=["/MT", "/Gd", "/GR", "/nologo"])
@@ -302,6 +309,9 @@ def configure_mingw(env):
## Build type
+ if env["tests"]:
+ env["windows_subsystem"] = "console"
+
if env["target"] == "release":
env.Append(CCFLAGS=["-msse2"])
@@ -334,7 +344,11 @@ def configure_mingw(env):
env.Append(CCFLAGS=["-g3"])
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
- env.Append(LINKFLAGS=["-Wl,--subsystem,windows"])
+ if env["windows_subsystem"] == "gui":
+ env.Append(LINKFLAGS=["-Wl,--subsystem,windows"])
+ else:
+ env.Append(LINKFLAGS=["-Wl,--subsystem,console"])
+ env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
## Compiler configuration
@@ -425,7 +439,7 @@ def configure_mingw(env):
else:
env.Append(LIBS=["cfgmgr32"])
- ## TODO !!! Reenable when OpenGLES Rendering Device is implemented !!!
+ ## TODO !!! Re-enable when OpenGLES Rendering Device is implemented !!!
# env.Append(CPPDEFINES=['OPENGL_ENABLED'])
env.Append(LIBS=["opengl32"])
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 9469e35536..dfbb734ee4 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "display_server_windows.h"
+
#include "core/io/marshalls.h"
+#include "core/math/geometry_2d.h"
#include "main/main.h"
#include "os_windows.h"
#include "scene/resources/texture.h"
@@ -42,7 +44,7 @@ static String format_error_message(DWORD id) {
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
- String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
+ String msg = "Error " + itos(id) + ": " + String::utf16((const char16_t *)messageBuffer, size);
LocalFree(messageBuffer);
@@ -78,7 +80,7 @@ String DisplayServerWindows::get_name() const {
}
void DisplayServerWindows::alert(const String &p_alert, const String &p_title) {
- MessageBoxW(nullptr, p_alert.c_str(), p_title.c_str(), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
+ MessageBoxW(nullptr, (LPCWSTR)(p_alert.utf16().get_data()), (LPCWSTR)(p_title.utf16().get_data()), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
}
void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
@@ -177,11 +179,12 @@ void DisplayServerWindows::clipboard_set(const String &p_text) {
}
EmptyClipboard();
- HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(CharType));
+ Char16String utf16 = text.utf16();
+ HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (utf16.length() + 1) * sizeof(WCHAR));
ERR_FAIL_COND_MSG(mem == nullptr, "Unable to allocate memory for clipboard contents.");
LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem);
- memcpy(lptstrCopy, text.c_str(), (text.length() + 1) * sizeof(CharType));
+ memcpy(lptstrCopy, utf16.get_data(), (utf16.length() + 1) * sizeof(WCHAR));
GlobalUnlock(mem);
SetClipboardData(CF_UNICODETEXT, mem);
@@ -218,7 +221,7 @@ String DisplayServerWindows::clipboard_get() const {
if (mem != nullptr) {
LPWSTR ptr = (LPWSTR)GlobalLock(mem);
if (ptr != nullptr) {
- ret = String((CharType *)ptr);
+ ret = String::utf16((const char16_t *)ptr);
GlobalUnlock(mem);
};
};
@@ -493,15 +496,21 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
wd.no_focus = true;
}
- _update_window_style(window_id);
+ return window_id;
+}
+
+void DisplayServerWindows::show_window(WindowID p_id) {
+ WindowData &wd = windows[p_id];
- ShowWindow(wd.hWnd, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
- if (!(p_flags & WINDOW_FLAG_NO_FOCUS_BIT)) {
+ if (p_id != MAIN_WINDOW_ID) {
+ _update_window_style(p_id);
+ }
+
+ ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
+ if (!wd.no_focus) {
SetForegroundWindow(wd.hWnd); // Slightly Higher Priority
SetFocus(wd.hWnd); // Sets Keyboard Focus To
}
-
- return window_id;
}
void DisplayServerWindows::delete_sub_window(WindowID p_window) {
@@ -587,7 +596,37 @@ void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_wi
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
- SetWindowTextW(windows[p_window].hWnd, p_title.c_str());
+ SetWindowTextW(windows[p_window].hWnd, (LPCWSTR)(p_title.utf16().get_data()));
+}
+
+void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ windows[p_window].mpath = p_region;
+ _update_window_mouse_passthrough(p_window);
+}
+
+void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) {
+ if (windows[p_window].mpath.size() == 0) {
+ SetWindowRgn(windows[p_window].hWnd, nullptr, TRUE);
+ } else {
+ POINT *points = (POINT *)memalloc(sizeof(POINT) * windows[p_window].mpath.size());
+ for (int i = 0; i < windows[p_window].mpath.size(); i++) {
+ if (windows[p_window].borderless) {
+ points[i].x = windows[p_window].mpath[i].x;
+ points[i].y = windows[p_window].mpath[i].y;
+ } else {
+ points[i].x = windows[p_window].mpath[i].x + GetSystemMetrics(SM_CXSIZEFRAME);
+ points[i].y = windows[p_window].mpath[i].y + GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
+ }
+ }
+
+ HRGN region = CreatePolygonRgn(points, windows[p_window].mpath.size(), ALTERNATE);
+ SetWindowRgn(windows[p_window].hWnd, region, TRUE);
+ DeleteObject(region);
+ memfree(points);
+ }
}
int DisplayServerWindows::window_get_current_screen(WindowID p_window) const {
@@ -1003,6 +1042,7 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
case WINDOW_FLAG_BORDERLESS: {
wd.borderless = p_enabled;
_update_window_style(p_window);
+ _update_window_mouse_passthrough(p_window);
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID && p_enabled, "Transient windows can't become on top");
@@ -1131,17 +1171,10 @@ void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowI
void DisplayServerWindows::console_set_visible(bool p_enabled) {
_THREAD_SAFE_METHOD_
- if (console_visible == p_enabled) {
+ if (console_visible == p_enabled)
return;
- }
- if (p_enabled && GetConsoleWindow() == nullptr) { // Open new console if not attached.
- own_console = true;
- AllocConsole();
- }
- if (own_console) { // Note: Do not hide parent console.
- ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE);
- console_visible = p_enabled;
- }
+ ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE);
+ console_visible = p_enabled;
}
bool DisplayServerWindows::is_console_visible() const {
@@ -1424,13 +1457,13 @@ String DisplayServerWindows::keyboard_get_layout_language(int p_index) const {
HKL *layouts = (HKL *)memalloc(layout_count * sizeof(HKL));
GetKeyboardLayoutList(layout_count, layouts);
- wchar_t buf[LOCALE_NAME_MAX_LENGTH];
- memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t));
+ WCHAR buf[LOCALE_NAME_MAX_LENGTH];
+ memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(WCHAR));
LCIDToLocaleName(MAKELCID(LOWORD(layouts[p_index]), SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
memfree(layouts);
- return String(buf).substr(0, 2);
+ return String::utf16((const char16_t *)buf).substr(0, 2);
}
String _get_full_layout_name_from_registry(HKL p_layout) {
@@ -1438,17 +1471,17 @@ String _get_full_layout_name_from_registry(HKL p_layout) {
String ret;
HKEY hkey;
- wchar_t layout_text[1024];
- memset(layout_text, 0, 1024 * sizeof(wchar_t));
+ WCHAR layout_text[1024];
+ memset(layout_text, 0, 1024 * sizeof(WCHAR));
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)id.c_str(), 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) {
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)(id.utf16().get_data()), 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) {
return ret;
}
DWORD buffer = 1024;
DWORD vtype = REG_SZ;
if (RegQueryValueExW(hkey, L"Layout Text", NULL, &vtype, (LPBYTE)layout_text, &buffer) == ERROR_SUCCESS) {
- ret = String(layout_text);
+ ret = String::utf16((const char16_t *)layout_text);
}
RegCloseKey(hkey);
return ret;
@@ -1464,15 +1497,15 @@ String DisplayServerWindows::keyboard_get_layout_name(int p_index) const {
String ret = _get_full_layout_name_from_registry(layouts[p_index]); // Try reading full name from Windows registry, fallback to locale name if failed (e.g. on Wine).
if (ret == String()) {
- wchar_t buf[LOCALE_NAME_MAX_LENGTH];
- memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t));
+ WCHAR buf[LOCALE_NAME_MAX_LENGTH];
+ memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(WCHAR));
LCIDToLocaleName(MAKELCID(LOWORD(layouts[p_index]), SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
- wchar_t name[1024];
- memset(name, 0, 1024 * sizeof(wchar_t));
+ WCHAR name[1024];
+ memset(name, 0, 1024 * sizeof(WCHAR));
GetLocaleInfoEx(buf, LOCALE_SLOCALIZEDDISPLAYNAME, (LPWSTR)&name, 1024);
- ret = String(name);
+ ret = String::utf16((const char16_t *)name);
}
memfree(layouts);
@@ -2712,7 +2745,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_DROPFILES: {
HDROP hDropInfo = (HDROP)wParam;
const int buffsize = 4096;
- wchar_t buf[buffsize];
+ WCHAR buf[buffsize];
int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF, nullptr, 0);
@@ -2720,7 +2753,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
for (int i = 0; i < fcount; i++) {
DragQueryFileW(hDropInfo, i, buf, buffsize);
- String file = buf;
+ String file = String::utf16((const char16_t *)buf);
files.push_back(file);
}
@@ -3022,18 +3055,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
shift_mem = false;
control_mem = false;
meta_mem = false;
-
- if (AttachConsole(ATTACH_PARENT_PROCESS)) {
- FILE *_file = nullptr;
- freopen_s(&_file, "CONOUT$", "w", stdout);
- freopen_s(&_file, "CONOUT$", "w", stderr);
- freopen_s(&_file, "CONIN$", "r", stdin);
-
- printf("\n");
- console_visible = true;
- } else {
- console_visible = false;
- }
+ console_visible = IsWindowVisible(GetConsoleWindow());
hInstance = ((OS_Windows *)OS::get_singleton())->get_hinstance();
pressrc = 0;
@@ -3139,9 +3161,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}
- ShowWindow(windows[MAIN_WINDOW_ID].hWnd, SW_SHOW); // Show The Window
- SetForegroundWindow(windows[MAIN_WINDOW_ID].hWnd); // Slightly Higher Priority
- SetFocus(windows[MAIN_WINDOW_ID].hWnd); // Sets Keyboard Focus To
+ show_window(MAIN_WINDOW_ID);
#if defined(VULKAN_ENABLED)
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 0ad8cd3d07..0fca2589ae 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -323,6 +323,8 @@ private:
HWND hWnd;
//layered window
+ Vector<Vector2> mpath;
+
bool preserve_window_size = false;
bool pre_fs_valid = false;
RECT pre_fs_rect;
@@ -405,7 +407,6 @@ private:
bool drop_events = false;
bool in_dispatch_input_event = false;
bool console_visible = false;
- bool own_console = false;
WNDCLASSEXW wc;
@@ -417,6 +418,7 @@ private:
void _touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx);
void _update_window_style(WindowID p_window, bool p_repaint = true, bool p_maximized = false);
+ void _update_window_mouse_passthrough(WindowID p_window);
void _update_real_mouse_position(WindowID p_window);
@@ -461,6 +463,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const;
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual void show_window(WindowID p_window);
virtual void delete_sub_window(WindowID p_window);
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
@@ -477,6 +480,7 @@ public:
virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID);
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 5b15896b0c..f73516b370 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -84,7 +84,7 @@ static String format_error_message(DWORD id) {
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
- String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
+ String msg = "Error " + itos(id) + ": " + String::utf16((const char16_t *)messageBuffer, size);
LocalFree(messageBuffer);
@@ -107,15 +107,11 @@ void RedirectIOToConsole() {
// set the screen buffer to be big enough to let us scroll text
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
-
- &coninfo);
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = MAX_CONSOLE_LINES;
- SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
-
- coninfo.dwSize);
+ SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDOUT to the console
@@ -265,10 +261,10 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
DLL_DIRECTORY_COOKIE cookie = nullptr;
if (p_also_set_library_path && has_dll_directory_api) {
- cookie = add_dll_directory(path.get_base_dir().c_str());
+ cookie = add_dll_directory((LPCWSTR)(path.get_base_dir().utf16().get_data()));
}
- p_library_handle = (void *)LoadLibraryExW(path.c_str(), nullptr, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
+ p_library_handle = (void *)LoadLibraryExW((LPCWSTR)(path.utf16().get_data()), nullptr, (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) {
@@ -407,7 +403,7 @@ uint64_t OS_Windows::get_ticks_usec() const {
String OS_Windows::_quote_command_line_argument(const String &p_text) const {
for (int i = 0; i < p_text.size(); i++) {
- CharType c = p_text[i];
+ char32_t c = p_text[i];
if (c == ' ' || c == '&' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '=' || c == ';' || c == '!' || c == '\'' || c == '+' || c == ',' || c == '`' || c == '~') {
return "\"" + p_text + "\"";
}
@@ -428,7 +424,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
// Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command.
argss = _quote_command_line_argument(argss);
- FILE *f = _wpopen(argss.c_str(), L"r");
+ FILE *f = _wpopen((LPCWSTR)(argss.utf16().get_data()), L"r");
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
char buf[65535];
@@ -463,13 +459,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- Vector<CharType> modstr; // Windows wants to change this no idea why.
- modstr.resize(cmdline.size());
- for (int i = 0; i < cmdline.size(); i++) {
- modstr.write[i] = cmdline[i];
- }
-
- int ret = CreateProcessW(nullptr, modstr.ptrw(), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ Char16String modstr = cmdline.utf16(); // Windows wants to change this no idea why.
+ int ret = CreateProcessW(nullptr, (LPWSTR)(modstr.ptrw()), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
if (p_blocking) {
@@ -509,26 +500,26 @@ int OS_Windows::get_process_id() const {
}
Error OS_Windows::set_cwd(const String &p_cwd) {
- if (_wchdir(p_cwd.c_str()) != 0)
+ if (_wchdir((LPCWSTR)(p_cwd.utf16().get_data())) != 0)
return ERR_CANT_OPEN;
return OK;
}
String OS_Windows::get_executable_path() const {
- wchar_t bufname[4096];
+ WCHAR bufname[4096];
GetModuleFileNameW(nullptr, bufname, 4096);
- String s = bufname;
+ String s = String::utf16((const char16_t *)bufname);
return s;
}
bool OS_Windows::has_environment(const String &p_var) const {
#ifdef MINGW_ENABLED
- return _wgetenv(p_var.c_str()) != nullptr;
+ return _wgetenv((LPCWSTR)(p_var.utf16().get_data())) != nullptr;
#else
- wchar_t *env;
+ WCHAR *env;
size_t len;
- _wdupenv_s(&env, &len, p_var.c_str());
+ _wdupenv_s(&env, &len, (LPCWSTR)(p_var.utf16().get_data()));
const bool has_env = env != nullptr;
free(env);
return has_env;
@@ -536,16 +527,16 @@ bool OS_Windows::has_environment(const String &p_var) const {
};
String OS_Windows::get_environment(const String &p_var) const {
- wchar_t wval[0x7Fff]; // MSDN says 32767 char is the maximum
- int wlen = GetEnvironmentVariableW(p_var.c_str(), wval, 0x7Fff);
+ WCHAR wval[0x7fff]; // MSDN says 32767 char is the maximum
+ int wlen = GetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), wval, 0x7fff);
if (wlen > 0) {
- return wval;
+ return String::utf16((const char16_t *)wval);
}
return "";
}
bool OS_Windows::set_environment(const String &p_var, const String &p_value) const {
- return (bool)SetEnvironmentVariableW(p_var.c_str(), p_value.c_str());
+ return (bool)SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), (LPCWSTR)(p_value.utf16().get_data()));
}
String OS_Windows::get_stdin_string(bool p_block) {
@@ -558,7 +549,7 @@ String OS_Windows::get_stdin_string(bool p_block) {
}
Error OS_Windows::shell_open(String p_uri) {
- ShellExecuteW(nullptr, nullptr, p_uri.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ ShellExecuteW(nullptr, nullptr, (LPCWSTR)(p_uri.utf16().get_data()), nullptr, nullptr, SW_SHOWNORMAL);
return OK;
}
@@ -701,7 +692,7 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const {
PWSTR szPath;
HRESULT res = SHGetKnownFolderPath(id, 0, nullptr, &szPath);
ERR_FAIL_COND_V(res != S_OK, String());
- String path = String(szPath);
+ String path = String::utf16((const char16_t *)szPath);
CoTaskMemFree(szPath);
return path;
}
@@ -727,7 +718,7 @@ String OS_Windows::get_user_data_dir() const {
String OS_Windows::get_unique_id() const {
HW_PROFILE_INFO HwProfInfo;
ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), "");
- return String(HwProfInfo.szHwProfileGuid);
+ return String::utf16((const char16_t *)(HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN);
}
bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
@@ -744,9 +735,11 @@ bool OS_Windows::is_disable_crash_handler() const {
Error OS_Windows::move_to_trash(const String &p_path) {
SHFILEOPSTRUCTW sf;
- WCHAR *from = new WCHAR[p_path.length() + 2];
- wcscpy_s(from, p_path.length() + 1, p_path.c_str());
- from[p_path.length() + 1] = 0;
+
+ Char16String utf16 = p_path.utf16();
+ WCHAR *from = new WCHAR[utf16.length() + 2];
+ wcscpy_s(from, utf16.length() + 1, (LPCWSTR)(utf16.get_data()));
+ from[utf16.length() + 1] = 0;
sf.hwnd = main_window;
sf.wFunc = FO_DELETE;
diff --git a/platform_methods.py b/platform_methods.py
index ec394d76d8..be4957475d 100644
--- a/platform_methods.py
+++ b/platform_methods.py
@@ -55,7 +55,7 @@ def run_in_subprocess(builder_function):
finally:
try:
os.remove(json_path)
- except (OSError, IOError) as e:
+ except OSError as e:
# Do not fail the entire build if it cannot delete a temporary file
print(
"WARNING: Could not delete temporary file: path=%r; [%s] %s" % (json_path, e.__class__.__name__, e)
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index e3a632c98a..dd21fcfe22 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -1291,7 +1291,7 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents"), "set_emission_rect_extents", "get_emission_rect_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index 416622e6d5..8c9432f2fa 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -101,7 +101,7 @@ void ParallaxBackground::_update_scroll() {
}
if (ignore_camera_zoom) {
- l->set_base_offset_and_scale(ofs, 1.0, screen_offset);
+ l->set_base_offset_and_scale((ofs + screen_offset * (scale - 1)) / scale, 1.0, screen_offset);
} else {
l->set_base_offset_and_scale(ofs, scale, screen_offset);
}
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 9fd24b5294..a00db36077 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -35,15 +35,15 @@
#include "physics_body_2d.h"
#include "servers/physics_server_2d.h"
-void RayCast2D::set_cast_to(const Vector2 &p_point) {
- cast_to = p_point;
+void RayCast2D::set_target_position(const Vector2 &p_point) {
+ target_position = p_point;
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update();
}
}
-Vector2 RayCast2D::get_cast_to() const {
- return cast_to;
+Vector2 RayCast2D::get_target_position() const {
+ return target_position;
}
void RayCast2D::set_collision_mask(uint32_t p_mask) {
@@ -160,8 +160,8 @@ void RayCast2D::_notification(int p_what) {
break;
}
Transform2D xf;
- xf.rotate(cast_to.angle());
- xf.translate(Vector2(cast_to.length(), 0));
+ xf.rotate(target_position.angle());
+ xf.translate(Vector2(target_position.length(), 0));
// Draw an arrow indicating where the RayCast is pointing to
Color draw_col = get_tree()->get_debug_collisions_color();
@@ -171,7 +171,7 @@ void RayCast2D::_notification(int p_what) {
draw_col.g = g;
draw_col.b = g;
}
- draw_line(Vector2(), cast_to, draw_col, 2);
+ draw_line(Vector2(), target_position, draw_col, 2);
Vector<Vector2> pts;
float tsize = 8;
pts.push_back(xf.xform(Vector2(tsize, 0)));
@@ -206,7 +206,7 @@ void RayCast2D::_update_raycast_state() {
Transform2D gt = get_global_transform();
- Vector2 to = cast_to;
+ Vector2 to = target_position;
if (to == Vector2()) {
to = Vector2(0, 0.01);
}
@@ -280,8 +280,8 @@ void RayCast2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast2D::is_enabled);
- ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast2D::set_cast_to);
- ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast2D::get_cast_to);
+ ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &RayCast2D::set_target_position);
+ ClassDB::bind_method(D_METHOD("get_target_position"), &RayCast2D::get_target_position);
ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast2D::is_colliding);
ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast2D::force_raycast_update);
@@ -316,7 +316,7 @@ void RayCast2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Collide With", "collide_with");
@@ -329,7 +329,7 @@ RayCast2D::RayCast2D() {
collided = false;
against_shape = 0;
collision_mask = 1;
- cast_to = Vector2(0, 50);
+ target_position = Vector2(0, 50);
exclude_parent_body = true;
collide_with_bodies = true;
collide_with_areas = false;
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 6accc264a0..14932f782b 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -46,7 +46,7 @@ class RayCast2D : public Node2D {
uint32_t collision_mask;
bool exclude_parent_body;
- Vector2 cast_to;
+ Vector2 target_position;
bool collide_with_areas;
bool collide_with_bodies;
@@ -66,8 +66,8 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
- void set_cast_to(const Vector2 &p_point);
- Vector2 get_cast_to() const;
+ void set_target_position(const Vector2 &p_point);
+ Vector2 get_target_position() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index 7e07019578..d1be93e55d 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -498,8 +498,8 @@ void Sprite2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v");
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, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
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");
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c7a809f6d8..c2951559a4 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -412,6 +412,9 @@ void TileMap::update_dirty_quadrants() {
vs->canvas_item_set_light_mask(canvas_item, get_light_mask());
vs->canvas_item_set_z_index(canvas_item, z_index);
+ vs->canvas_item_set_default_texture_filter(canvas_item, RS::CanvasItemTextureFilter(CanvasItem::get_texture_filter()));
+ vs->canvas_item_set_default_texture_repeat(canvas_item, RS::CanvasItemTextureRepeat(CanvasItem::get_texture_repeat()));
+
q.canvas_items.push_back(canvas_item);
if (debug_shapes) {
@@ -1687,6 +1690,28 @@ bool TileMap::get_clip_uv() const {
return clip_uv;
}
+void TileMap::set_texture_filter(TextureFilter p_texture_filter) {
+ CanvasItem::set_texture_filter(p_texture_filter);
+ for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
+ Quadrant &q = F->get();
+ for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
+ RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(E->get(), RS::CanvasItemTextureFilter(p_texture_filter));
+ _make_quadrant_dirty(F);
+ }
+ }
+}
+
+void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
+ CanvasItem::set_texture_repeat(p_texture_repeat);
+ for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
+ Quadrant &q = F->get();
+ for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
+ RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(E->get(), RS::CanvasItemTextureRepeat(p_texture_repeat));
+ _make_quadrant_dirty(F);
+ }
+ }
+}
+
String TileMap::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 7a2a3e412c..b9dd8f5405 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -342,6 +342,10 @@ public:
String get_configuration_warning() const override;
+ virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter) override;
+
+ virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) override;
+
void fix_invalid_tiles();
void clear();
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp
index 56367e9bdd..e7f3f53ca9 100644
--- a/scene/3d/collision_shape_3d.cpp
+++ b/scene/3d/collision_shape_3d.cpp
@@ -44,23 +44,36 @@
//TODO: Implement CylinderShape and HeightMapShape?
-void CollisionShape3D::make_convex_from_brothers() {
+void CollisionShape3D::make_convex_from_siblings() {
Node *p = get_parent();
if (!p) {
return;
}
+ Vector<Vector3> vertices;
+
for (int i = 0; i < p->get_child_count(); i++) {
Node *n = p->get_child(i);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
if (mi) {
Ref<Mesh> m = mi->get_mesh();
if (m.is_valid()) {
- Ref<Shape3D> s = m->create_convex_shape();
- set_shape(s);
+ for (int j = 0; j < m->get_surface_count(); j++) {
+ Array a = m->surface_get_arrays(j);
+ if (!a.empty()) {
+ Vector<Vector3> v = a[RenderingServer::ARRAY_VERTEX];
+ for (int k = 0; k < v.size(); k++) {
+ vertices.append(mi->get_transform().xform(v[k]));
+ }
+ }
+ }
}
}
}
+
+ Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
+ shape->set_points(vertices);
+ set_shape(shape);
}
void CollisionShape3D::_update_in_shape_owner(bool p_xform_only) {
@@ -137,8 +150,8 @@ void CollisionShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape3D::get_shape);
ClassDB::bind_method(D_METHOD("set_disabled", "enable"), &CollisionShape3D::set_disabled);
ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionShape3D::is_disabled);
- ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape3D::make_convex_from_brothers);
- ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings);
+ ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape);
diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h
index a32a3efeb6..35f40d27b1 100644
--- a/scene/3d/collision_shape_3d.h
+++ b/scene/3d/collision_shape_3d.h
@@ -60,7 +60,7 @@ protected:
static void _bind_methods();
public:
- void make_convex_from_brothers();
+ void make_convex_from_siblings();
void set_shape(const Ref<Shape3D> &p_shape);
Ref<Shape3D> get_shape() const;
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index ad8760251f..ded83b75ac 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -1345,7 +1345,7 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index c4480e3ed2..6fa0fc6ecb 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -301,6 +301,36 @@ void GPUParticles3D::_validate_property(PropertyInfo &property) const {
}
}
+void GPUParticles3D::emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+ RS::get_singleton()->particles_emit(particles, p_transform, p_velocity, p_color, p_custom, p_emit_flags);
+}
+
+void GPUParticles3D::_attach_sub_emitter() {
+ Node *n = get_node_or_null(sub_emitter);
+ if (n) {
+ GPUParticles3D *sen = Object::cast_to<GPUParticles3D>(n);
+ if (sen && sen != this) {
+ RS::get_singleton()->particles_set_subemitter(particles, sen->particles);
+ }
+ }
+}
+
+void GPUParticles3D::set_sub_emitter(const NodePath &p_path) {
+ if (is_inside_tree()) {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ }
+
+ sub_emitter = p_path;
+
+ if (is_inside_tree() && sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+}
+
+NodePath GPUParticles3D::get_sub_emitter() const {
+ return sub_emitter;
+}
+
void GPUParticles3D::_notification(int p_what) {
if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
if (can_process()) {
@@ -319,6 +349,16 @@ void GPUParticles3D::_notification(int p_what) {
}
}
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ if (sub_emitter != NodePath()) {
+ _attach_sub_emitter();
+ }
+ }
+
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+ RS::get_singleton()->particles_set_subemitter(particles, RID());
+ }
+
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
// make sure particles are updated before rendering occurs if they were active before
if (is_visible_in_tree() && !RS::get_singleton()->particles_is_inactive(particles)) {
@@ -369,8 +409,14 @@ void GPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("restart"), &GPUParticles3D::restart);
ClassDB::bind_method(D_METHOD("capture_aabb"), &GPUParticles3D::capture_aabb);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter", "path"), &GPUParticles3D::set_sub_emitter);
+ ClassDB::bind_method(D_METHOD("get_sub_emitter"), &GPUParticles3D::get_sub_emitter);
+
+ ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles3D::emit_particle);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles3D"), "set_sub_emitter", "get_sub_emitter");
ADD_GROUP("Time", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
@@ -396,6 +442,12 @@ void GPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_ROTATION_SCALE);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR);
+ BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM);
+
BIND_CONSTANT(MAX_DRAW_PASSES);
}
diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h
index e04473727d..0d8dadd31d 100644
--- a/scene/3d/gpu_particles_3d.h
+++ b/scene/3d/gpu_particles_3d.h
@@ -64,6 +64,7 @@ private:
bool local_coords;
int fixed_fps;
bool fractional_delta;
+ NodePath sub_emitter;
Ref<Material> process_material;
@@ -71,6 +72,8 @@ private:
Vector<Ref<Mesh>> draw_passes;
+ void _attach_sub_emitter();
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -121,13 +124,27 @@ public:
virtual String get_configuration_warning() const override;
+ void set_sub_emitter(const NodePath &p_path);
+ NodePath get_sub_emitter() const;
+
void restart();
+ enum EmitFlags {
+ EMIT_FLAG_POSITION = RS::PARTICLES_EMIT_FLAG_POSITION,
+ EMIT_FLAG_ROTATION_SCALE = RS::PARTICLES_EMIT_FLAG_ROTATION_SCALE,
+ EMIT_FLAG_VELOCITY = RS::PARTICLES_EMIT_FLAG_VELOCITY,
+ EMIT_FLAG_COLOR = RS::PARTICLES_EMIT_FLAG_COLOR,
+ EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM
+ };
+
+ void emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
+
AABB capture_aabb() const;
GPUParticles3D();
~GPUParticles3D();
};
VARIANT_ENUM_CAST(GPUParticles3D::DrawOrder)
+VARIANT_ENUM_CAST(GPUParticles3D::EmitFlags)
#endif // PARTICLES_H
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index 2a922e3cda..69f09ef569 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -35,8 +35,8 @@
#include "mesh_instance_3d.h"
#include "servers/physics_server_3d.h"
-void RayCast3D::set_cast_to(const Vector3 &p_point) {
- cast_to = p_point;
+void RayCast3D::set_target_position(const Vector3 &p_point) {
+ target_position = p_point;
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
}
@@ -45,8 +45,8 @@ void RayCast3D::set_cast_to(const Vector3 &p_point) {
}
}
-Vector3 RayCast3D::get_cast_to() const {
- return cast_to;
+Vector3 RayCast3D::get_target_position() const {
+ return target_position;
}
void RayCast3D::set_collision_mask(uint32_t p_mask) {
@@ -202,7 +202,7 @@ void RayCast3D::_update_raycast_state() {
Transform gt = get_global_transform();
- Vector3 to = cast_to;
+ Vector3 to = target_position;
if (to == Vector3()) {
to = Vector3(0, 0.01, 0);
}
@@ -276,8 +276,8 @@ void RayCast3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast3D::is_enabled);
- ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast3D::set_cast_to);
- ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast3D::get_cast_to);
+ ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &RayCast3D::set_target_position);
+ ClassDB::bind_method(D_METHOD("get_target_position"), &RayCast3D::get_target_position);
ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast3D::is_colliding);
ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast3D::force_raycast_update);
@@ -312,7 +312,7 @@ void RayCast3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Collide With", "collide_with");
@@ -360,7 +360,7 @@ void RayCast3D::_update_debug_shape() {
Vector<Vector3> verts;
verts.push_back(Vector3());
- verts.push_back(cast_to);
+ verts.push_back(target_position);
a[Mesh::ARRAY_VERTEX] = verts;
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
@@ -387,7 +387,7 @@ RayCast3D::RayCast3D() {
collided = false;
against_shape = 0;
collision_mask = 1;
- cast_to = Vector3(0, -1, 0);
+ target_position = Vector3(0, -1, 0);
debug_shape = nullptr;
exclude_parent_body = true;
collide_with_areas = false;
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index 8f617e5491..f4fe7ba621 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -43,7 +43,7 @@ class RayCast3D : public Node3D {
Vector3 collision_point;
Vector3 collision_normal;
- Vector3 cast_to;
+ Vector3 target_position;
Set<RID> exclude;
uint32_t collision_mask;
@@ -74,8 +74,8 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
- void set_cast_to(const Vector3 &p_point);
- Vector3 get_cast_to() const;
+ void set_target_position(const Vector3 &p_point);
+ Vector3 get_target_position() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index a267c57f5e..d3d7cdc1ce 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -106,7 +106,7 @@ SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
offset = obj_tocopy.offset;
}
-SoftBody3D::PinnedPoint SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
+SoftBody3D::PinnedPoint &SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
point_index = obj.point_index;
spatial_attachment_path = obj.spatial_attachment_path;
spatial_attachment = obj.spatial_attachment;
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 85cfb81637..c59a0b3aa3 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -74,7 +74,7 @@ public:
PinnedPoint();
PinnedPoint(const PinnedPoint &obj_tocopy);
- PinnedPoint operator=(const PinnedPoint &obj);
+ PinnedPoint &operator=(const PinnedPoint &obj);
};
private:
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 3b76cb6499..6e38196ba6 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -667,8 +667,8 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
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, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
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_");
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 6fef44481a..2e77d20d4e 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -60,7 +60,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mouse_button = p_event;
bool ui_accept = p_event->is_action("ui_accept") && !p_event->is_echo();
- bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) > 0;
+ bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) != 0;
if (button_masked || ui_accept) {
on_action_event(p_event);
return;
@@ -326,12 +326,12 @@ bool BaseButton::is_keep_pressed_outside() const {
return keep_pressed_outside;
}
-void BaseButton::set_shortcut(const Ref<ShortCut> &p_shortcut) {
+void BaseButton::set_shortcut(const Ref<Shortcut> &p_shortcut) {
shortcut = p_shortcut;
set_process_unhandled_input(shortcut.is_valid());
}
-Ref<ShortCut> BaseButton::get_shortcut() const {
+Ref<Shortcut> BaseButton::get_shortcut() const {
return shortcut;
}
@@ -345,7 +345,7 @@ String BaseButton::get_tooltip(const Point2 &p_pos) const {
String tooltip = Control::get_tooltip(p_pos);
if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->is_valid()) {
String text = shortcut->get_name() + " (" + shortcut->get_as_text() + ")";
- if (shortcut->get_name().nocasecmp_to(tooltip) != 0) {
+ if (tooltip != String() && shortcut->get_name().nocasecmp_to(tooltip) != 0) {
text += "\n" + tooltip;
}
tooltip = text;
@@ -414,7 +414,7 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask", PROPERTY_HINT_FLAGS, "Mouse Left, Mouse Right, Mouse Middle"), "set_button_mask", "get_button_mask");
ADD_PROPERTY(PropertyInfo(Variant::INT, "enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_enabled_focus_mode", "get_enabled_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_pressed_outside"), "set_keep_pressed_outside", "is_keep_pressed_outside");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_shortcut", "get_shortcut");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "group", PROPERTY_HINT_RESOURCE_TYPE, "ButtonGroup"), "set_button_group", "get_button_group");
BIND_ENUM_CONSTANT(DRAW_NORMAL);
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 12272446d5..8e71931f8b 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -50,7 +50,7 @@ private:
bool shortcut_in_tooltip;
bool keep_pressed_outside;
FocusMode enabled_focus_mode;
- Ref<ShortCut> shortcut;
+ Ref<Shortcut> shortcut;
ActionMode action_mode;
struct Status {
@@ -118,8 +118,8 @@ public:
void set_enabled_focus_mode(FocusMode p_mode);
FocusMode get_enabled_focus_mode() const;
- void set_shortcut(const Ref<ShortCut> &p_shortcut);
- Ref<ShortCut> get_shortcut() const;
+ void set_shortcut(const Ref<Shortcut> &p_shortcut);
+ Ref<Shortcut> get_shortcut() const;
virtual String get_tooltip(const Point2 &p_pos) const override;
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
new file mode 100644
index 0000000000..56cf432b38
--- /dev/null
+++ b/scene/gui/code_edit.cpp
@@ -0,0 +1,444 @@
+/*************************************************************************/
+/* code_edit.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "code_edit.h"
+
+void CodeEdit::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_ENTER_TREE: {
+ set_gutter_width(main_gutter, cache.row_height);
+ set_gutter_width(line_number_gutter, (line_number_digits + 1) * cache.font->get_char_size('0').width);
+ set_gutter_width(fold_gutter, cache.row_height / 1.2);
+
+ breakpoint_color = get_theme_color("breakpoint_color");
+ breakpoint_icon = get_theme_icon("breakpoint");
+
+ bookmark_color = get_theme_color("bookmark_color");
+ bookmark_icon = get_theme_icon("bookmark");
+
+ executing_line_color = get_theme_color("executing_line_color");
+ executing_line_icon = get_theme_icon("executing_line");
+
+ line_number_color = get_theme_color("line_number_color");
+
+ folding_color = get_theme_color("code_folding_color");
+ can_fold_icon = get_theme_icon("can_fold");
+ folded_icon = get_theme_icon("folded");
+ } break;
+ case NOTIFICATION_DRAW: {
+ } break;
+ }
+}
+
+/* Main Gutter */
+void CodeEdit::_update_draw_main_gutter() {
+ set_gutter_draw(main_gutter, draw_breakpoints || draw_bookmarks || draw_executing_lines);
+}
+
+void CodeEdit::set_draw_breakpoints_gutter(bool p_draw) {
+ draw_breakpoints = p_draw;
+ set_gutter_clickable(main_gutter, p_draw);
+ _update_draw_main_gutter();
+}
+
+bool CodeEdit::is_drawing_breakpoints_gutter() const {
+ return draw_breakpoints;
+}
+
+void CodeEdit::set_draw_bookmarks_gutter(bool p_draw) {
+ draw_bookmarks = p_draw;
+ _update_draw_main_gutter();
+}
+
+bool CodeEdit::is_drawing_bookmarks_gutter() const {
+ return draw_bookmarks;
+}
+
+void CodeEdit::set_draw_executing_lines_gutter(bool p_draw) {
+ draw_executing_lines = p_draw;
+ _update_draw_main_gutter();
+}
+
+bool CodeEdit::is_drawing_executing_lines_gutter() const {
+ return draw_executing_lines;
+}
+
+void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
+ if (draw_breakpoints && is_line_breakpointed(p_line)) {
+ int padding = p_region.size.x / 6;
+
+ Rect2 breakpoint_region = p_region;
+ breakpoint_region.position += Point2(padding, padding);
+ breakpoint_region.size -= Point2(padding, padding) * 2;
+ breakpoint_icon->draw_rect(get_canvas_item(), breakpoint_region, false, breakpoint_color);
+ }
+
+ if (draw_bookmarks && is_line_bookmarked(p_line)) {
+ int horizontal_padding = p_region.size.x / 2;
+ int vertical_padding = p_region.size.y / 4;
+
+ Rect2 bookmark_region = p_region;
+ bookmark_region.position += Point2(horizontal_padding, 0);
+ bookmark_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
+ bookmark_icon->draw_rect(get_canvas_item(), bookmark_region, false, bookmark_color);
+ }
+
+ if (draw_executing_lines && is_line_executing(p_line)) {
+ int horizontal_padding = p_region.size.x / 10;
+ int vertical_padding = p_region.size.y / 4;
+
+ Rect2 executing_line_region = p_region;
+ executing_line_region.position += Point2(horizontal_padding, vertical_padding);
+ executing_line_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
+ executing_line_icon->draw_rect(get_canvas_item(), executing_line_region, false, executing_line_color);
+ }
+}
+
+// Breakpoints
+void CodeEdit::set_line_as_breakpoint(int p_line, bool p_breakpointed) {
+ int mask = get_line_gutter_metadata(p_line, main_gutter);
+ set_line_gutter_metadata(p_line, main_gutter, p_breakpointed ? mask | MAIN_GUTTER_BREAKPOINT : mask & ~MAIN_GUTTER_BREAKPOINT);
+ if (p_breakpointed) {
+ breakpointed_lines[p_line] = true;
+ } else if (breakpointed_lines.has(p_line)) {
+ breakpointed_lines.erase(p_line);
+ }
+ emit_signal("breakpoint_toggled", p_line);
+}
+
+bool CodeEdit::is_line_breakpointed(int p_line) const {
+ return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_BREAKPOINT;
+}
+
+void CodeEdit::clear_breakpointed_lines() {
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_breakpointed(i)) {
+ set_line_as_breakpoint(i, false);
+ }
+ }
+}
+
+Array CodeEdit::get_breakpointed_lines() const {
+ Array ret;
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_breakpointed(i)) {
+ ret.append(i);
+ }
+ }
+ return ret;
+}
+
+// Bookmarks
+void CodeEdit::set_line_as_bookmarked(int p_line, bool p_bookmarked) {
+ int mask = get_line_gutter_metadata(p_line, main_gutter);
+ set_line_gutter_metadata(p_line, main_gutter, p_bookmarked ? mask | MAIN_GUTTER_BOOKMARK : mask & ~MAIN_GUTTER_BOOKMARK);
+}
+
+bool CodeEdit::is_line_bookmarked(int p_line) const {
+ return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_BOOKMARK;
+}
+
+void CodeEdit::clear_bookmarked_lines() {
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_bookmarked(i)) {
+ set_line_as_bookmarked(i, false);
+ }
+ }
+}
+
+Array CodeEdit::get_bookmarked_lines() const {
+ Array ret;
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_bookmarked(i)) {
+ ret.append(i);
+ }
+ }
+ return ret;
+}
+
+// executing lines
+void CodeEdit::set_line_as_executing(int p_line, bool p_executing) {
+ int mask = get_line_gutter_metadata(p_line, main_gutter);
+ set_line_gutter_metadata(p_line, main_gutter, p_executing ? mask | MAIN_GUTTER_EXECUTING : mask & ~MAIN_GUTTER_EXECUTING);
+}
+
+bool CodeEdit::is_line_executing(int p_line) const {
+ return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_EXECUTING;
+}
+
+void CodeEdit::clear_executing_lines() {
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_executing(i)) {
+ set_line_as_executing(i, false);
+ }
+ }
+}
+
+Array CodeEdit::get_executing_lines() const {
+ Array ret;
+ for (int i = 0; i < get_line_count(); i++) {
+ if (is_line_executing(i)) {
+ ret.append(i);
+ }
+ }
+ return ret;
+}
+
+/* Line numbers */
+void CodeEdit::set_draw_line_numbers(bool p_draw) {
+ set_gutter_draw(line_number_gutter, p_draw);
+}
+
+bool CodeEdit::is_draw_line_numbers_enabled() const {
+ return is_gutter_drawn(line_number_gutter);
+}
+
+void CodeEdit::set_line_numbers_zero_padded(bool p_zero_padded) {
+ p_zero_padded ? line_number_padding = "0" : line_number_padding = " ";
+ update();
+}
+
+bool CodeEdit::is_line_numbers_zero_padded() const {
+ return line_number_padding == "0";
+}
+
+void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
+ String fc = String::num(p_line + 1).lpad(line_number_digits, line_number_padding);
+
+ int yofs = p_region.position.y + (cache.row_height - cache.font->get_height()) / 2;
+ Color number_color = get_line_gutter_item_color(p_line, line_number_gutter);
+ if (number_color == Color(1, 1, 1)) {
+ number_color = line_number_color;
+ }
+ cache.font->draw(get_canvas_item(), Point2(p_region.position.x, yofs + cache.font->get_ascent()), fc, number_color);
+}
+
+/* Fold Gutter */
+void CodeEdit::set_draw_fold_gutter(bool p_draw) {
+ set_gutter_draw(fold_gutter, p_draw);
+}
+
+bool CodeEdit::is_drawing_fold_gutter() const {
+ return is_gutter_drawn(fold_gutter);
+}
+
+void CodeEdit::_fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_region) {
+ if (!can_fold(p_line) && !is_folded(p_line)) {
+ set_line_gutter_clickable(p_line, fold_gutter, false);
+ return;
+ }
+ set_line_gutter_clickable(p_line, fold_gutter, true);
+
+ int horizontal_padding = p_region.size.x / 10;
+ int vertical_padding = p_region.size.y / 6;
+
+ p_region.position += Point2(horizontal_padding, vertical_padding);
+ p_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
+
+ if (can_fold(p_line)) {
+ can_fold_icon->draw_rect(get_canvas_item(), p_region, false, folding_color);
+ return;
+ }
+ folded_icon->draw_rect(get_canvas_item(), p_region, false, folding_color);
+}
+
+void CodeEdit::_bind_methods() {
+ /* Main Gutter */
+ ClassDB::bind_method(D_METHOD("_main_gutter_draw_callback"), &CodeEdit::_main_gutter_draw_callback);
+
+ ClassDB::bind_method(D_METHOD("set_draw_breakpoints_gutter", "enable"), &CodeEdit::set_draw_breakpoints_gutter);
+ ClassDB::bind_method(D_METHOD("is_drawing_breakpoints_gutter"), &CodeEdit::is_drawing_breakpoints_gutter);
+
+ ClassDB::bind_method(D_METHOD("set_draw_bookmarks_gutter", "enable"), &CodeEdit::set_draw_bookmarks_gutter);
+ ClassDB::bind_method(D_METHOD("is_drawing_bookmarks_gutter"), &CodeEdit::is_drawing_bookmarks_gutter);
+
+ ClassDB::bind_method(D_METHOD("set_draw_executing_lines_gutter", "enable"), &CodeEdit::set_draw_executing_lines_gutter);
+ ClassDB::bind_method(D_METHOD("is_drawing_executing_lines_gutter"), &CodeEdit::is_drawing_executing_lines_gutter);
+
+ // Breakpoints
+ ClassDB::bind_method(D_METHOD("set_line_as_breakpoint", "line", "breakpointed"), &CodeEdit::set_line_as_breakpoint);
+ ClassDB::bind_method(D_METHOD("is_line_breakpointed", "line"), &CodeEdit::is_line_breakpointed);
+ ClassDB::bind_method(D_METHOD("clear_breakpointed_lines"), &CodeEdit::clear_breakpointed_lines);
+ ClassDB::bind_method(D_METHOD("get_breakpointed_lines"), &CodeEdit::get_breakpointed_lines);
+
+ // Bookmarks
+ ClassDB::bind_method(D_METHOD("set_line_as_bookmarked", "line", "bookmarked"), &CodeEdit::set_line_as_bookmarked);
+ ClassDB::bind_method(D_METHOD("is_line_bookmarked", "line"), &CodeEdit::is_line_bookmarked);
+ ClassDB::bind_method(D_METHOD("clear_bookmarked_lines"), &CodeEdit::clear_bookmarked_lines);
+ ClassDB::bind_method(D_METHOD("get_bookmarked_lines"), &CodeEdit::get_bookmarked_lines);
+
+ // executing lines
+ ClassDB::bind_method(D_METHOD("set_line_as_executing", "line", "executing"), &CodeEdit::set_line_as_executing);
+ ClassDB::bind_method(D_METHOD("is_line_executing", "line"), &CodeEdit::is_line_executing);
+ ClassDB::bind_method(D_METHOD("clear_executing_lines"), &CodeEdit::clear_executing_lines);
+ ClassDB::bind_method(D_METHOD("get_executing_lines"), &CodeEdit::get_executing_lines);
+
+ /* Line numbers */
+ ClassDB::bind_method(D_METHOD("_line_number_draw_callback"), &CodeEdit::_line_number_draw_callback);
+
+ ClassDB::bind_method(D_METHOD("set_draw_line_numbers", "enable"), &CodeEdit::set_draw_line_numbers);
+ ClassDB::bind_method(D_METHOD("is_draw_line_numbers_enabled"), &CodeEdit::is_draw_line_numbers_enabled);
+ ClassDB::bind_method(D_METHOD("set_line_numbers_zero_padded", "enable"), &CodeEdit::set_line_numbers_zero_padded);
+ ClassDB::bind_method(D_METHOD("is_line_numbers_zero_padded"), &CodeEdit::is_line_numbers_zero_padded);
+
+ /* Fold Gutter */
+ ClassDB::bind_method(D_METHOD("_fold_gutter_draw_callback"), &CodeEdit::_fold_gutter_draw_callback);
+
+ ClassDB::bind_method(D_METHOD("set_draw_fold_gutter", "enable"), &CodeEdit::set_draw_fold_gutter);
+ ClassDB::bind_method(D_METHOD("is_drawing_fold_gutter"), &CodeEdit::is_drawing_fold_gutter);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_breakpoints_gutter"), "set_draw_breakpoints_gutter", "is_drawing_breakpoints_gutter");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_bookmarks"), "set_draw_bookmarks_gutter", "is_drawing_bookmarks_gutter");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_executing_lines"), "set_draw_executing_lines_gutter", "is_drawing_executing_lines_gutter");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_line_numbers"), "set_draw_line_numbers", "is_draw_line_numbers_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "zero_pad_line_numbers"), "set_line_numbers_zero_padded", "is_line_numbers_zero_padded");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter");
+
+ ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::INT, "line")));
+}
+
+void CodeEdit::_gutter_clicked(int p_line, int p_gutter) {
+ if (p_gutter == main_gutter) {
+ if (draw_breakpoints) {
+ set_line_as_breakpoint(p_line, !is_line_breakpointed(p_line));
+ }
+ return;
+ }
+
+ if (p_gutter == line_number_gutter) {
+ cursor_set_line(p_line);
+ return;
+ }
+
+ if (p_gutter == fold_gutter) {
+ if (is_folded(p_line)) {
+ unfold_line(p_line);
+ } else if (can_fold(p_line)) {
+ fold_line(p_line);
+ }
+ return;
+ }
+}
+
+void CodeEdit::_lines_edited_from(int p_from_line, int p_to_line) {
+ if (p_from_line == p_to_line) {
+ return;
+ }
+
+ int lc = get_line_count();
+ line_number_digits = 1;
+ while (lc /= 10) {
+ line_number_digits++;
+ }
+ set_gutter_width(line_number_gutter, (line_number_digits + 1) * cache.font->get_char_size('0').width);
+
+ int from_line = MIN(p_from_line, p_to_line);
+ int line_count = (p_to_line - p_from_line);
+ List<int> breakpoints;
+ breakpointed_lines.get_key_list(&breakpoints);
+ for (const List<int>::Element *E = breakpoints.front(); E; E = E->next()) {
+ int line = E->get();
+ if (line <= from_line) {
+ continue;
+ }
+ breakpointed_lines.erase(line);
+
+ emit_signal("breakpoint_toggled", line);
+ if (line_count > 0 || line >= p_from_line) {
+ emit_signal("breakpoint_toggled", line + line_count);
+ breakpointed_lines[line + line_count] = true;
+ continue;
+ }
+ }
+}
+
+void CodeEdit::_update_gutter_indexes() {
+ for (int i = 0; i < get_gutter_count(); i++) {
+ if (get_gutter_name(i) == "main_gutter") {
+ main_gutter = i;
+ continue;
+ }
+
+ if (get_gutter_name(i) == "line_numbers") {
+ line_number_gutter = i;
+ continue;
+ }
+
+ if (get_gutter_name(i) == "fold_gutter") {
+ fold_gutter = i;
+ continue;
+ }
+ }
+}
+
+CodeEdit::CodeEdit() {
+ /* Gutters */
+ int gutter_idx = 0;
+
+ /* Main Gutter */
+ add_gutter();
+ set_gutter_name(gutter_idx, "main_gutter");
+ set_gutter_draw(gutter_idx, false);
+ set_gutter_overwritable(gutter_idx, true);
+ set_gutter_type(gutter_idx, GUTTER_TPYE_CUSTOM);
+ set_gutter_custom_draw(gutter_idx, this, "_main_gutter_draw_callback");
+ gutter_idx++;
+
+ /* Line numbers */
+ add_gutter();
+ set_gutter_name(gutter_idx, "line_numbers");
+ set_gutter_draw(gutter_idx, false);
+ set_gutter_type(gutter_idx, GUTTER_TPYE_CUSTOM);
+ set_gutter_custom_draw(gutter_idx, this, "_line_number_draw_callback");
+ gutter_idx++;
+
+ /* Fold Gutter */
+ add_gutter();
+ set_gutter_name(gutter_idx, "fold_gutter");
+ set_gutter_draw(gutter_idx, false);
+ set_gutter_type(gutter_idx, GUTTER_TPYE_CUSTOM);
+ set_gutter_custom_draw(gutter_idx, this, "_fold_gutter_draw_callback");
+ gutter_idx++;
+
+ connect("lines_edited_from", callable_mp(this, &CodeEdit::_lines_edited_from));
+ connect("gutter_clicked", callable_mp(this, &CodeEdit::_gutter_clicked));
+
+ connect("gutter_added", callable_mp(this, &CodeEdit::_update_gutter_indexes));
+ connect("gutter_removed", callable_mp(this, &CodeEdit::_update_gutter_indexes));
+ _update_gutter_indexes();
+}
+
+CodeEdit::~CodeEdit() {
+}
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
new file mode 100644
index 0000000000..c989e5ed79
--- /dev/null
+++ b/scene/gui/code_edit.h
@@ -0,0 +1,135 @@
+/*************************************************************************/
+/* code_edit.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef CODEEDIT_H
+#define CODEEDIT_H
+
+#include "scene/gui/text_edit.h"
+
+class CodeEdit : public TextEdit {
+ GDCLASS(CodeEdit, TextEdit)
+
+private:
+ /* Main Gutter */
+ enum MainGutterType {
+ MAIN_GUTTER_BREAKPOINT = 0x01,
+ MAIN_GUTTER_BOOKMARK = 0x02,
+ MAIN_GUTTER_EXECUTING = 0x04
+ };
+
+ int main_gutter = -1;
+ void _update_draw_main_gutter();
+ void _main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region);
+
+ // breakpoints
+ HashMap<int, bool> breakpointed_lines;
+ bool draw_breakpoints = false;
+ Color breakpoint_color = Color(1, 1, 1);
+ Ref<Texture2D> breakpoint_icon = Ref<Texture2D>();
+
+ // bookmarks
+ bool draw_bookmarks = false;
+ Color bookmark_color = Color(1, 1, 1);
+ Ref<Texture2D> bookmark_icon = Ref<Texture2D>();
+
+ // executing lines
+ bool draw_executing_lines = false;
+ Color executing_line_color = Color(1, 1, 1);
+ Ref<Texture2D> executing_line_icon = Ref<Texture2D>();
+
+ /* Line numbers */
+ int line_number_gutter = -1;
+ int line_number_digits = 0;
+ String line_number_padding = " ";
+ Color line_number_color = Color(1, 1, 1);
+ void _line_number_draw_callback(int p_line, int p_gutter, const Rect2 &p_region);
+
+ /* Fold Gutter */
+ int fold_gutter = -1;
+ bool draw_fold_gutter = false;
+ Color folding_color = Color(1, 1, 1);
+ Ref<Texture2D> can_fold_icon = Ref<Texture2D>();
+ Ref<Texture2D> folded_icon = Ref<Texture2D>();
+ void _fold_gutter_draw_callback(int p_line, int p_gutter, Rect2 p_region);
+
+ void _gutter_clicked(int p_line, int p_gutter);
+ void _lines_edited_from(int p_from_line, int p_to_line);
+
+ void _update_gutter_indexes();
+
+protected:
+ void _notification(int p_what);
+
+ static void _bind_methods();
+
+public:
+ /* Main Gutter */
+ void set_draw_breakpoints_gutter(bool p_draw);
+ bool is_drawing_breakpoints_gutter() const;
+
+ void set_draw_bookmarks_gutter(bool p_draw);
+ bool is_drawing_bookmarks_gutter() const;
+
+ void set_draw_executing_lines_gutter(bool p_draw);
+ bool is_drawing_executing_lines_gutter() const;
+
+ // breakpoints
+ void set_line_as_breakpoint(int p_line, bool p_breakpointed);
+ bool is_line_breakpointed(int p_line) const;
+ void clear_breakpointed_lines();
+ Array get_breakpointed_lines() const;
+
+ // bookmarks
+ void set_line_as_bookmarked(int p_line, bool p_bookmarked);
+ bool is_line_bookmarked(int p_line) const;
+ void clear_bookmarked_lines();
+ Array get_bookmarked_lines() const;
+
+ // executing lines
+ void set_line_as_executing(int p_line, bool p_executing);
+ bool is_line_executing(int p_line) const;
+ void clear_executing_lines();
+ Array get_executing_lines() const;
+
+ /* Line numbers */
+ void set_draw_line_numbers(bool p_draw);
+ bool is_draw_line_numbers_enabled() const;
+ void set_line_numbers_zero_padded(bool p_zero_padded);
+ bool is_line_numbers_zero_padded() const;
+
+ /* Fold gutter */
+ void set_draw_fold_gutter(bool p_draw);
+ bool is_drawing_fold_gutter() const;
+
+ CodeEdit();
+ ~CodeEdit();
+};
+
+#endif // CODEEDIT_H
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index fafbb298b7..cbe0367c7b 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -873,6 +873,7 @@ void ColorPickerButton::_color_changed(const Color &p_color) {
void ColorPickerButton::_modal_closed() {
emit_signal("popup_closed");
+ set_pressed(false);
}
void ColorPickerButton::pressed() {
@@ -976,9 +977,8 @@ void ColorPickerButton::_update_picker() {
popup->add_child(picker);
add_child(popup);
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
- popup->connect("modal_closed", callable_mp(this, &ColorPickerButton::_modal_closed));
popup->connect("about_to_popup", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true));
- popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false));
+ popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
emit_signal("picker_created");
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 11b4c9e857..467d252c81 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -262,6 +262,7 @@ void GraphEdit::remove_child_notify(Node *p_child) {
if (gn) {
gn->disconnect("offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved));
gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised));
+ gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update));
}
}
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index f49acc1b96..9e3418a5c9 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -188,7 +188,7 @@ void Label::_notification(int p_what) {
int spaces = 0;
while (to && to->char_pos >= 0) {
taken += to->pixel_width;
- if (to != from && to->space_count) {
+ if (to->space_count) {
spaces += to->space_count;
}
to = to->next;
@@ -235,8 +235,8 @@ void Label::_notification(int p_what) {
float x_ofs_shadow = x_ofs;
for (int i = 0; i < from->word_len; i++) {
if (visible_chars < 0 || chars_total_shadow < visible_chars) {
- CharType c = xl_text[i + pos];
- CharType n = xl_text[i + pos + 1];
+ char32_t c = xl_text[i + pos];
+ char32_t n = xl_text[i + pos + 1];
if (uppercase) {
c = String::char_uppercase(c);
n = String::char_uppercase(n);
@@ -255,8 +255,8 @@ void Label::_notification(int p_what) {
}
for (int i = 0; i < from->word_len; i++) {
if (visible_chars < 0 || chars_total < visible_chars) {
- CharType c = xl_text[i + pos];
- CharType n = xl_text[i + pos + 1];
+ char32_t c = xl_text[i + pos];
+ char32_t n = xl_text[i + pos + 1];
if (uppercase) {
c = String::char_uppercase(c);
n = String::char_uppercase(n);
@@ -308,7 +308,7 @@ int Label::get_longest_line_width() const {
real_t line_width = 0;
for (int i = 0; i < xl_text.size(); i++) {
- CharType current = xl_text[i];
+ char32_t current = xl_text[i];
if (uppercase) {
current = String::char_uppercase(current);
}
@@ -390,7 +390,7 @@ void Label::regenerate_word_cache() {
WordCache *last = nullptr;
for (int i = 0; i <= xl_text.length(); i++) {
- CharType current = i < xl_text.length() ? xl_text[i] : L' '; //always a space at the end, so the algo works
+ char32_t current = i < xl_text.length() ? xl_text[i] : L' '; //always a space at the end, so the algo works
if (uppercase) {
current = String::char_uppercase(current);
@@ -420,6 +420,22 @@ void Label::regenerate_word_cache() {
wc->space_count = space_count;
current_word_size = 0;
space_count = 0;
+ } else if ((i == xl_text.length() || current == '\n') && last != nullptr && space_count != 0) {
+ //in case there are trailing white spaces we add a placeholder word cache with just the spaces
+ WordCache *wc = memnew(WordCache);
+ if (word_cache) {
+ last->next = wc;
+ } else {
+ word_cache = wc;
+ }
+ last = wc;
+
+ wc->pixel_width = 0;
+ wc->char_pos = 0;
+ wc->word_len = 0;
+ wc->space_count = space_count;
+ current_word_size = 0;
+ space_count = 0;
}
if (current == '\n') {
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 14167531a5..1b8f04297d 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -42,7 +42,7 @@
#include "editor/editor_settings.h"
#endif
#include "scene/main/window.h"
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return !is_symbol(c);
}
@@ -313,7 +313,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
}
- return;
} break;
case KEY_BACKSPACE: {
@@ -582,7 +581,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) {
if (editable) {
selection_delete();
- CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 };
+ char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 };
int prev_len = text.length();
append_at_cursor(ucodestr);
if (text.length() != prev_len) {
@@ -807,8 +806,8 @@ void LineEdit::_notification(int p_what) {
break;
}
- CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
- CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
+ char32_t cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
+ char32_t next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
int im_char_width = font->get_char_size(cchar, next).width;
if ((x_ofs + im_char_width) > ofs_max) {
@@ -830,8 +829,8 @@ void LineEdit::_notification(int p_what) {
}
}
- CharType cchar = (pass && !text.empty()) ? secret_character[0] : t[char_ofs];
- CharType next = (pass && !text.empty()) ? secret_character[0] : t[char_ofs + 1];
+ char32_t cchar = (pass && !text.empty()) ? secret_character[0] : t[char_ofs];
+ char32_t 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.
@@ -870,8 +869,8 @@ void LineEdit::_notification(int p_what) {
break;
}
- CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
- CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
+ char32_t cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
+ char32_t next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
int im_char_width = font->get_char_size(cchar, next).width;
if ((x_ofs + im_char_width) > ofs_max) {
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 5fc5f9b669..8a65aa5032 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -41,55 +41,71 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
}
}
-void Popup::_parent_focused() {
- _close_pressed();
+void Popup::_initialize_visible_parents() {
+ visible_parents.clear();
+
+ Window *parent_window = this;
+ while (parent_window) {
+ parent_window = parent_window->get_parent_visible_window();
+ if (parent_window) {
+ visible_parents.push_back(parent_window);
+ parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
+ parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
+ }
+ }
+}
+
+void Popup::_deinitialize_visible_parents() {
+ for (uint32_t i = 0; i < visible_parents.size(); ++i) {
+ visible_parents[i]->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
+ visible_parents[i]->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
+ }
+
+ visible_parents.clear();
}
void Popup::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
- parent_visible = get_parent_visible_window();
- if (parent_visible) {
- parent_visible->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- }
+ _initialize_visible_parents();
} else {
- if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- parent_visible = nullptr;
- }
-
+ _deinitialize_visible_parents();
emit_signal("popup_hide");
}
} break;
- case NOTIFICATION_EXIT_TREE: {
- if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- parent_visible = nullptr;
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
+ if (has_focus()) {
+ popped_up = true;
}
} break;
+ case NOTIFICATION_EXIT_TREE: {
+ _deinitialize_visible_parents();
+ } break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
_close_pressed();
-
+ } break;
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
+ _close_pressed();
} break;
}
}
-void Popup::_close_pressed() {
- Window *parent_window = parent_visible;
- if (parent_visible) {
- parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
- parent_visible = nullptr;
+void Popup::_parent_focused() {
+ if (popped_up) {
+ _close_pressed();
}
+}
+
+void Popup::_close_pressed() {
+ popped_up = false;
+
+ _deinitialize_visible_parents();
call_deferred("hide");
emit_signal("cancelled");
-
- if (parent_window) {
- //parent_window->grab_focus();
- }
}
void Popup::set_as_minsize() {
@@ -126,12 +142,32 @@ Rect2i Popup::_popup_adjust_rect() const {
current.position.y = parent.position.y;
}
+ if (current.size.y > parent.size.y) {
+ current.size.y = parent.size.y;
+ }
+
+ if (current.size.x > parent.size.x) {
+ current.size.x = parent.size.x;
+ }
+
+ // Early out if max size not set.
+ Size2i max_size = get_max_size();
+ if (max_size <= Size2()) {
+ return current;
+ }
+
+ if (current.size.x > max_size.x) {
+ current.size.x = max_size.x;
+ }
+
+ if (current.size.y > max_size.y) {
+ current.size.y = max_size.y;
+ }
+
return current;
}
Popup::Popup() {
- parent_visible = nullptr;
-
set_wrap_controls(true);
set_visible(false);
set_transient(true);
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 97c08095d3..3e5b89ccf3 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -33,12 +33,19 @@
#include "scene/main/window.h"
+#include "core/local_vector.h"
+
class Popup : public Window {
GDCLASS(Popup, Window);
- Window *parent_visible;
+ LocalVector<Window *> visible_parents;
+ bool popped_up = false;
void _input_from_window(const Ref<InputEvent> &p_event);
+
+ void _initialize_visible_parents();
+ void _deinitialize_visible_parents();
+
void _parent_focused();
protected:
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 6e19b820e0..578d8a96e8 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -35,7 +35,6 @@
#include "core/os/os.h"
#include "core/print_string.h"
#include "core/translation.h"
-#include "scene/gui/control.h"
String PopupMenu::_get_accel_text(int p_item) const {
ERR_FAIL_INDEX_V(p_item, items.size(), String());
@@ -52,7 +51,8 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
int vseparation = get_theme_constant("vseparation");
int hseparation = get_theme_constant("hseparation");
- Size2 minsize = get_theme_stylebox("panel")->get_minimum_size();
+ Size2 minsize = get_theme_stylebox("panel")->get_minimum_size(); // Accounts for margin in the margin container
+ minsize.x += scroll_container->get_v_scrollbar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content
Ref<Font> font = get_theme_font("font");
float max_w = 0;
@@ -64,13 +64,10 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
for (int i = 0; i < items.size(); i++) {
Size2 size;
- if (!items[i].icon.is_null()) {
- Size2 icon_size = items[i].icon->get_size();
- size.height = MAX(icon_size.height, font_h);
- icon_w = MAX(icon_size.width + hseparation, icon_w);
- } else {
- size.height = font_h;
- }
+
+ Size2 icon_size = items[i].get_icon_size();
+ size.height = MAX(icon_size.height, font_h);
+ icon_w = MAX(icon_size.width, icon_w);
size.width += items[i].h_ofs;
@@ -104,39 +101,71 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
minsize.width += check_w;
}
+ if (is_inside_tree()) {
+ int height_limit = get_usable_parent_rect().size.height;
+ if (minsize.height > height_limit) {
+ minsize.height = height_limit;
+ }
+ }
+
return minsize;
}
+int PopupMenu::_get_items_total_height() const {
+ int font_height = get_theme_font("font")->get_height();
+ int vsep = get_theme_constant("vseparation");
+
+ // Get total height of all items by taking max of icon height and font height
+ int items_total_height = 0;
+ for (int i = 0; i < items.size(); i++) {
+ items_total_height += MAX(items[i].get_icon_size().height, font_height) + vsep;
+ }
+
+ // Subtract a separator which is not needed for the last item.
+ return items_total_height - vsep;
+}
+
+void PopupMenu::_scroll_to_item(int p_item) {
+ ERR_FAIL_INDEX(p_item, items.size());
+ ERR_FAIL_COND(p_item < 0);
+
+ // Scroll item into view (upwards)
+ if (items[p_item]._ofs_cache < -control->get_position().y) {
+ int amnt_over = items[p_item]._ofs_cache + control->get_position().y;
+ scroll_container->set_v_scroll(scroll_container->get_v_scroll() + amnt_over);
+ }
+
+ // Scroll item into view (downwards)
+ if (items[p_item]._ofs_cache + items[p_item]._height_cache > -control->get_position().y + scroll_container->get_size().height) {
+ int amnt_over = items[p_item]._ofs_cache + items[p_item]._height_cache + control->get_position().y - scroll_container->get_size().height;
+ scroll_container->set_v_scroll(scroll_container->get_v_scroll() + amnt_over);
+ }
+}
+
int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
if (p_over.x < 0 || p_over.x >= get_size().width) {
return -1;
}
- Ref<StyleBox> style = get_theme_stylebox("panel");
+ Ref<StyleBox> style = get_theme_stylebox("panel"); // Accounts for margin in the margin container
+
+ int vseparation = get_theme_constant("vseparation");
+ float font_h = get_theme_font("font")->get_height();
- Point2 ofs = style->get_offset();
+ Point2 ofs = style->get_offset() + Point2(0, vseparation / 2);
if (ofs.y > p_over.y) {
return -1;
}
- Ref<Font> font = get_theme_font("font");
- int vseparation = get_theme_constant("vseparation");
- float font_h = font->get_height();
-
for (int i = 0; i < items.size(); i++) {
- ofs.y += vseparation;
- float h;
-
- if (!items[i].icon.is_null()) {
- Size2 icon_size = items[i].icon->get_size();
- h = MAX(icon_size.height, font_h);
- } else {
- h = font_h;
+ if (i > 0) {
+ ofs.y += vseparation;
}
- ofs.y += h;
- if (p_over.y < ofs.y) {
+ ofs.y += MAX(items[i].get_icon_size().height, font_h);
+
+ if (p_over.y - control->get_position().y < ofs.y) {
return i;
}
}
@@ -147,43 +176,51 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
void PopupMenu::_activate_submenu(int over) {
Node *n = get_node(items[over].submenu);
ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
- Popup *pm = Object::cast_to<Popup>(n);
- ERR_FAIL_COND_MSG(!pm, "Item subnode is not a Popup: " + items[over].submenu + ".");
- if (pm->is_visible()) {
+ Popup *submenu_popup = Object::cast_to<Popup>(n);
+ ERR_FAIL_COND_MSG(!submenu_popup, "Item subnode is not a Popup: " + items[over].submenu + ".");
+ if (submenu_popup->is_visible()) {
return; //already visible!
}
- Point2 p = get_position();
- Rect2 pr(p, get_size());
Ref<StyleBox> style = get_theme_stylebox("panel");
+ int vsep = get_theme_constant("vseparation");
+
+ Point2 this_pos = get_position();
+ Rect2 this_rect(this_pos, get_size());
+
+ float scroll_offset = control->get_position().y;
- Point2 pos = p + Point2(get_size().width, items[over]._ofs_cache - style->get_offset().y);
- Size2 size = pm->get_size();
- // fix pos
- if (pos.x + size.width > get_parent_rect().size.width) {
- pos.x = p.x - size.width;
+ Point2 submenu_pos = this_pos + Point2(this_rect.size.width, items[over]._ofs_cache + scroll_offset);
+ Size2 submenu_size = submenu_popup->get_size();
+
+ // Fix pos if going outside parent rect
+ if (submenu_pos.x + submenu_size.width > get_parent_rect().size.width) {
+ submenu_pos.x = this_pos.x - submenu_size.width;
}
- pm->set_position(pos);
- // pm->set_scale(get_global_transform().get_scale());
- pm->popup();
-
- PopupMenu *pum = Object::cast_to<PopupMenu>(pm);
- if (pum) {
- pr.position -= pum->get_position();
- pum->clear_autohide_areas();
- pum->add_autohide_area(Rect2(pr.position.x, pr.position.y, pr.size.x, items[over]._ofs_cache));
- if (over < items.size() - 1) {
- int from = items[over + 1]._ofs_cache;
- pum->add_autohide_area(Rect2(pr.position.x, pr.position.y + from, pr.size.x, pr.size.y - from));
+ submenu_popup->set_position(submenu_pos);
+ submenu_popup->set_as_minsize(); // Shrink the popup size to it's contents.
+ submenu_popup->popup();
+
+ // Set autohide areas
+ PopupMenu *submenu_pum = Object::cast_to<PopupMenu>(submenu_popup);
+ if (submenu_pum) {
+ // Make the position of the parent popup relative to submenu popup
+ this_rect.position = this_rect.position - submenu_pum->get_position();
+
+ // Autohide area above the submenu item
+ submenu_pum->clear_autohide_areas();
+ submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, items[over]._ofs_cache + scroll_offset + style->get_offset().height - vsep / 2));
+
+ // If there is an area below the submenu item, add an autohide area there.
+ if (items[over]._ofs_cache + items[over]._height_cache + scroll_offset <= control->get_size().height) {
+ int from = items[over]._ofs_cache + items[over]._height_cache + scroll_offset + vsep / 2 + style->get_offset().height;
+ submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from));
}
}
}
void PopupMenu::_submenu_timeout() {
- //if (!has_focus()) {
- // return; //do not activate if not has focus
- //}
if (mouse_over == submenu_over) {
_activate_submenu(mouse_over);
}
@@ -191,70 +228,34 @@ void PopupMenu::_submenu_timeout() {
submenu_over = -1;
}
-void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {
- int vseparation = get_theme_constant("vseparation");
- Ref<Font> font = get_theme_font("font");
-
- Rect2 visible_rect = get_usable_parent_rect();
-
- int dy = (vseparation + font->get_height()) * 3 * p_factor;
- if (dy > 0) {
- const float global_top = get_position().y;
- const float limit = global_top < visible_rect.position.y ? visible_rect.position.y - global_top : 0;
- dy = MIN(dy, limit);
- } else if (dy < 0) {
- const float global_bottom = get_position().y + get_size().y;
- const float viewport_height = visible_rect.position.y + visible_rect.size.y;
- const float limit = global_bottom > viewport_height ? global_bottom - viewport_height : 0;
- dy = -MIN(-dy, limit);
- }
-
- if (dy == 0) {
- return;
- }
-
- set_position(get_position() + Vector2(0, dy));
-
- Ref<InputEventMouseMotion> ie;
- ie.instance();
- ie->set_position(p_over - Vector2(0, dy));
- _gui_input(ie);
-}
-
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event->is_action("ui_down") && p_event->is_pressed()) {
+ if (p_event->is_action("ui_down") && p_event->is_pressed() && mouse_over != items.size() - 1) {
int search_from = mouse_over + 1;
if (search_from >= items.size()) {
search_from = 0;
}
for (int i = search_from; i < items.size(); i++) {
- if (i < 0 || i >= items.size()) {
- continue;
- }
-
if (!items[i].separator && !items[i].disabled) {
mouse_over = i;
emit_signal("id_focused", i);
+ _scroll_to_item(i);
control->update();
set_input_as_handled();
break;
}
}
- } else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
+ } else if (p_event->is_action("ui_up") && p_event->is_pressed() && mouse_over != 0) {
int search_from = mouse_over - 1;
if (search_from < 0) {
search_from = items.size() - 1;
}
for (int i = search_from; i >= 0; i--) {
- if (i >= items.size()) {
- continue;
- }
-
if (!items[i].separator && !items[i].disabled) {
mouse_over = i;
emit_signal("id_focused", i);
+ _scroll_to_item(i);
control->update();
set_input_as_handled();
break;
@@ -282,65 +283,61 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
}
+ // Make an area which does not include v scrollbar, so that items are not activated when dragging scrollbar.
+ Rect2 item_clickable_area = scroll_container->get_rect();
+ if (scroll_container->get_v_scrollbar()->is_visible_in_tree()) {
+ item_clickable_area.size.width -= scroll_container->get_v_scrollbar()->get_size().width;
+ }
+
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
- if (b->is_pressed()) {
+ if (!item_clickable_area.has_point(b->get_position())) {
return;
}
int button_idx = b->get_button_index();
- switch (button_idx) {
- case BUTTON_WHEEL_DOWN: {
- _scroll(-b->get_factor(), b->get_position());
- } break;
- case BUTTON_WHEEL_UP: {
- _scroll(b->get_factor(), b->get_position());
- } break;
- default: {
- // Allow activating item by releasing the LMB or any that was down when the popup appeared
- if (button_idx == BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) {
- bool was_during_grabbed_click = during_grabbed_click;
- during_grabbed_click = false;
- initial_button_mask = 0;
-
- int over = _get_mouse_over(b->get_position());
-
- if (invalidated_click) {
- invalidated_click = false;
- break;
- }
- if (over < 0) {
- if (!was_during_grabbed_click) {
- hide();
- }
- break; //non-activable
- }
+ if (b->is_pressed() || (!b->is_pressed() && during_grabbed_click)) {
+ // Allow activating item by releasing the LMB or any that was down when the popup appeared.
+ // However, if button was not held when opening menu, do not allow release to activate item.
+ if (button_idx == BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) {
+ bool was_during_grabbed_click = during_grabbed_click;
+ during_grabbed_click = false;
+ initial_button_mask = 0;
+
+ // Disable clicks under a time threshold to avoid selection right when opening the popup.
+ uint64_t now = OS::get_singleton()->get_ticks_msec();
+ uint64_t diff = now - popup_time_msec;
+ if (diff < 100) {
+ return;
+ }
- if (items[over].separator || items[over].disabled) {
- break;
+ int over = _get_mouse_over(b->get_position());
+ if (over < 0) {
+ if (!was_during_grabbed_click) {
+ hide();
}
+ return;
+ }
- if (items[over].submenu != "") {
- _activate_submenu(over);
- return;
- }
- activate_item(over);
+ if (items[over].separator || items[over].disabled) {
+ return;
+ }
+
+ if (items[over].submenu != "") {
+ _activate_submenu(over);
+ return;
}
+ activate_item(over);
}
}
-
- //control->update();
}
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
- if (invalidated_click) {
- moved += m->get_relative();
- if (moved.length() > 4) {
- invalidated_click = false;
- }
+ if (!item_clickable_area.has_point(m->get_position())) {
+ return;
}
for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
@@ -370,11 +367,6 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
}
- Ref<InputEventPanGesture> pan_gesture = p_event;
- if (pan_gesture.is_valid()) {
- _scroll(-pan_gesture->get_delta().y, pan_gesture->get_position());
- }
-
Ref<InputEventKey> k = p_event;
if (allow_search && k.is_valid() && k->get_unicode() && k->is_pressed()) {
@@ -407,6 +399,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
if (items[i].text.findn(search_string) == 0) {
mouse_over = i;
emit_signal("id_focused", i);
+ _scroll_to_item(i);
control->update();
set_input_as_handled();
break;
@@ -415,9 +408,13 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
}
-void PopupMenu::_draw() {
+void PopupMenu::_draw_items() {
+ control->set_custom_minimum_size(Size2(0, _get_items_total_height()));
RID ci = control->get_canvas_item();
- Size2 size = get_size();
+
+ Size2 margin_size;
+ margin_size.width = margin_container->get_theme_constant("margin_right") + margin_container->get_theme_constant("margin_left");
+ margin_size.height = margin_container->get_theme_constant("margin_top") + margin_container->get_theme_constant("margin_bottom");
Ref<StyleBox> style = get_theme_stylebox("panel");
Ref<StyleBox> hover = get_theme_stylebox("hover");
@@ -430,8 +427,6 @@ void PopupMenu::_draw() {
Ref<StyleBox> labeled_separator_left = get_theme_stylebox("labeled_separator_left");
Ref<StyleBox> labeled_separator_right = get_theme_stylebox("labeled_separator_right");
- style->draw(ci, Rect2(Point2(), get_size()));
- Point2 ofs = style->get_offset();
int vseparation = get_theme_constant("vseparation");
int hseparation = get_theme_constant("hseparation");
Color font_color = get_theme_color("font_color");
@@ -440,13 +435,14 @@ void PopupMenu::_draw() {
Color font_color_hover = get_theme_color("font_color_hover");
float font_h = font->get_height();
- // Add the check and the wider icon to the offset of all items.
+ float scroll_width = scroll_container->get_v_scrollbar()->is_visible_in_tree() ? scroll_container->get_v_scrollbar()->get_size().width : 0;
+ float display_width = control->get_size().width - scroll_width;
+
+ // Find the widest icon and whether any items have a checkbox, and store the offsets for each.
float icon_ofs = 0.0;
bool has_check = false;
for (int i = 0; i < items.size(); i++) {
- if (!items[i].icon.is_null()) {
- icon_ofs = MAX(items[i].icon->get_size().width, icon_ofs);
- }
+ icon_ofs = MAX(items[i].get_icon_size().width, icon_ofs);
if (items[i].checkable_type) {
has_check = true;
@@ -461,65 +457,68 @@ void PopupMenu::_draw() {
check_ofs = MAX(get_theme_icon("checked")->get_width(), get_theme_icon("radio_checked")->get_width()) + hseparation;
}
+ Point2 ofs = Point2();
+
+ // Loop through all items and draw each.
for (int i = 0; i < items.size(); i++) {
+ // If not the first item, add the separation space between items.
if (i > 0) {
ofs.y += vseparation;
}
- Point2 item_ofs = ofs;
- Size2 icon_size;
- float h;
- if (!items[i].icon.is_null()) {
- icon_size = items[i].icon->get_size();
- h = MAX(icon_size.height, font_h);
- } else {
- h = font_h;
- }
+ Point2 item_ofs = ofs;
+ Size2 icon_size = items[i].get_icon_size();
+ float h = MAX(icon_size.height, font_h);
if (i == mouse_over) {
- hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation)));
+ hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(display_width + hseparation * 2, h + vseparation)));
}
String text = items[i].xl_text;
+ // Separator
item_ofs.x += items[i].h_ofs;
if (items[i].separator) {
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
if (text != String()) {
- int ss = font->get_string_size(text).width;
- int center = (get_size().width) / 2;
- int l = center - ss / 2;
- int r = center + ss / 2;
- if (l > item_ofs.x) {
- labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, l - item_ofs.x), sep_h)));
+ int text_size = font->get_string_size(text).width;
+ int text_center = display_width / 2;
+ int text_left = text_center - text_size / 2;
+ int text_right = text_center + text_size / 2;
+ if (text_left > item_ofs.x) {
+ labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, text_left - item_ofs.x), sep_h)));
}
- if (r < get_size().width - style->get_margin(MARGIN_RIGHT)) {
- labeled_separator_right->draw(ci, Rect2(Point2(r, item_ofs.y + Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, get_size().width - style->get_margin(MARGIN_RIGHT) - r), sep_h)));
+ if (text_right < display_width) {
+ labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, display_width - text_right), sep_h)));
}
} else {
- separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(get_size().width - style->get_minimum_size().width, sep_h)));
+ separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(display_width, sep_h)));
}
}
Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1);
+ // Checkboxes
if (items[i].checkable_type) {
Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color);
}
+ // Icon
if (!items[i].icon.is_null()) {
items[i].icon->draw(ci, item_ofs + Size2(check_ofs, 0) + Point2(0, Math::floor((h - icon_size.height) / 2.0)), icon_color);
}
+ // Submenu arrow on right hand side
if (items[i].submenu != "") {
- submenu->draw(ci, Point2(size.width - style->get_margin(MARGIN_RIGHT) - submenu->get_width(), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
+ submenu->draw(ci, Point2(display_width - submenu->get_width(), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
}
+ // Text
item_ofs.y += font->get_ascent();
if (items[i].separator) {
if (text != String()) {
- int center = (get_size().width - font->get_string_size(text).width) / 2;
+ int center = (display_width - font->get_string_size(text).width) / 2;
font->draw(ci, Point2(center, item_ofs.y + Math::floor((h - font_h) / 2.0)), text, font_color_disabled);
}
} else {
@@ -527,19 +526,27 @@ void PopupMenu::_draw() {
font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color));
}
+ // Accelerator / Shortcut
if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
- //accelerator
- String text2 = _get_accel_text(i);
- item_ofs.x = size.width - style->get_margin(MARGIN_RIGHT) - font->get_string_size(text2).width;
- font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text2, i == mouse_over ? font_color_hover : font_color_accel);
+ String sc_text = _get_accel_text(i);
+ item_ofs.x = display_width - font->get_string_size(sc_text).width;
+ font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), sc_text, i == mouse_over ? font_color_hover : font_color_accel);
}
+ // Cache the item vertical offset from the first item and the height
items.write[i]._ofs_cache = ofs.y;
+ items.write[i]._height_cache = h;
ofs.y += h;
}
}
+void PopupMenu::_draw_background() {
+ Ref<StyleBox> style = get_theme_stylebox("panel");
+ RID ci2 = margin_container->get_canvas_item();
+ style->draw(ci2, Rect2(Point2(), margin_container->get_size()));
+}
+
void PopupMenu::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -617,6 +624,13 @@ void PopupMenu::_notification(int p_what) {
if (get_window_id() != DisplayServer::INVALID_WINDOW_ID) {
set_process_internal(true);
}
+
+ // Set margin on the margin container
+ Ref<StyleBox> panel_style = get_theme_stylebox("panel");
+ margin_container->add_theme_constant_override("margin_top", panel_style->get_margin(Margin::MARGIN_TOP));
+ margin_container->add_theme_constant_override("margin_bottom", panel_style->get_margin(Margin::MARGIN_BOTTOM));
+ margin_container->add_theme_constant_override("margin_left", panel_style->get_margin(Margin::MARGIN_LEFT));
+ margin_container->add_theme_constant_override("margin_right", panel_style->get_margin(Margin::MARGIN_RIGHT));
}
} break;
}
@@ -698,7 +712,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
}
#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \
- ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid ShortCut."); \
+ ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \
_ref_shortcut(p_shortcut); \
item.text = p_shortcut->get_name(); \
item.xl_text = tr(item.text); \
@@ -706,7 +720,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
item.shortcut = p_shortcut; \
item.shortcut_is_global = p_global;
-void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
items.push_back(item);
@@ -714,7 +728,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g
child_controls_changed();
}
-void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -723,7 +737,7 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortC
child_controls_changed();
}
-void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
@@ -732,7 +746,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo
child_controls_changed();
}
-void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -742,7 +756,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
child_controls_changed();
}
-void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
@@ -751,7 +765,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_
child_controls_changed();
}
-void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
+void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id, bool p_global) {
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -912,8 +926,8 @@ String PopupMenu::get_item_tooltip(int p_idx) const {
return items[p_idx].tooltip;
}
-Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<ShortCut>());
+Ref<Shortcut> PopupMenu::get_item_shortcut(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Shortcut>());
return items[p_idx].shortcut;
}
@@ -951,7 +965,7 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
control->update();
}
-void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global) {
+void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) {
ERR_FAIL_INDEX(p_idx, items.size());
if (items[p_idx].shortcut.is_valid()) {
_unref_shortcut(items[p_idx].shortcut);
@@ -1190,7 +1204,7 @@ Array PopupMenu::_get_items() const {
return items;
}
-void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
+void PopupMenu::_ref_shortcut(Ref<Shortcut> p_sc) {
if (!shortcut_refcount.has(p_sc)) {
shortcut_refcount[p_sc] = 1;
p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
@@ -1199,7 +1213,7 @@ void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
}
}
-void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) {
+void PopupMenu::_unref_shortcut(Ref<Shortcut> p_sc) {
ERR_FAIL_COND(!shortcut_refcount.has(p_sc));
shortcut_refcount[p_sc]--;
if (shortcut_refcount[p_sc] == 0) {
@@ -1424,23 +1438,38 @@ void PopupMenu::_bind_methods() {
void PopupMenu::popup(const Rect2 &p_bounds) {
moved = Vector2();
- invalidated_click = true;
+ popup_time_msec = OS::get_singleton()->get_ticks_msec();
+ set_as_minsize();
Popup::popup(p_bounds);
}
PopupMenu::PopupMenu() {
+ // Margin Container
+ margin_container = memnew(MarginContainer);
+ margin_container->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ add_child(margin_container);
+ margin_container->connect("draw", callable_mp(this, &PopupMenu::_draw_background));
+
+ // Scroll Container
+ scroll_container = memnew(ScrollContainer);
+ scroll_container->set_clip_contents(true);
+ margin_container->add_child(scroll_container);
+
+ // The control which will display the items
control = memnew(Control);
- add_child(control);
-
+ control->set_clip_contents(false);
control->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ control->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ scroll_container->add_child(control);
+ control->connect("draw", callable_mp(this, &PopupMenu::_draw_items));
+
connect("window_input", callable_mp(this, &PopupMenu::_gui_input));
- control->connect("draw", callable_mp(this, &PopupMenu::_draw));
mouse_over = -1;
submenu_over = -1;
initial_button_mask = 0;
during_grabbed_click = false;
- invalidated_click = false;
allow_search = true;
search_time_msec = 0;
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 43cd7a54e9..e8f82ba869 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -31,7 +31,9 @@
#ifndef POPUP_MENU_H
#define POPUP_MENU_H
+#include "scene/gui/margin_container.h"
#include "scene/gui/popup.h"
+#include "scene/gui/scroll_container.h"
#include "scene/gui/shortcut.h"
class PopupMenu : public Popup {
@@ -57,11 +59,17 @@ class PopupMenu : public Popup {
String tooltip;
uint32_t accel;
int _ofs_cache;
+ int _height_cache;
int h_ofs;
- Ref<ShortCut> shortcut;
+ Ref<Shortcut> shortcut;
bool shortcut_is_global;
bool shortcut_is_disabled;
+ // Returns (0,0) if icon is null.
+ Size2 get_icon_size() const {
+ return icon.is_null() ? Size2() : icon->get_size();
+ }
+
Item() {
checked = false;
checkable_type = CHECKABLE_TYPE_NONE;
@@ -71,6 +79,7 @@ class PopupMenu : public Popup {
accel = 0;
disabled = false;
_ofs_cache = 0;
+ _height_cache = 0;
h_ofs = 0;
shortcut_is_global = false;
shortcut_is_disabled = false;
@@ -88,12 +97,15 @@ class PopupMenu : public Popup {
String _get_accel_text(int p_item) const;
int _get_mouse_over(const Point2 &p_over) const;
virtual Size2 _get_contents_minimum_size() const override;
- void _scroll(float p_factor, const Point2 &p_over);
+
+ int _get_items_total_height() const;
+ void _scroll_to_item(int p_item);
+
void _gui_input(const Ref<InputEvent> &p_event);
void _activate_submenu(int over);
void _submenu_timeout();
- bool invalidated_click;
+ uint64_t popup_time_msec = 0;
bool hide_on_item_selection;
bool hide_on_checkable_item_selection;
bool hide_on_multistate_item_selection;
@@ -102,18 +114,21 @@ class PopupMenu : public Popup {
Array _get_items() const;
void _set_items(const Array &p_items);
- Map<Ref<ShortCut>, int> shortcut_refcount;
+ Map<Ref<Shortcut>, int> shortcut_refcount;
- void _ref_shortcut(Ref<ShortCut> p_sc);
- void _unref_shortcut(Ref<ShortCut> p_sc);
+ void _ref_shortcut(Ref<Shortcut> p_sc);
+ void _unref_shortcut(Ref<Shortcut> p_sc);
bool allow_search;
uint64_t search_time_msec;
String search_string;
+ MarginContainer *margin_container;
+ ScrollContainer *scroll_container;
Control *control;
- void _draw();
+ void _draw_items();
+ void _draw_background();
protected:
friend class MenuButton;
@@ -130,12 +145,12 @@ public:
void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0);
- void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
- void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_radio_check_shortcut(const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
+ void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<Shortcut> &p_shortcut, int p_id = -1, bool p_global = false);
void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1);
@@ -151,7 +166,7 @@ public:
void set_item_as_checkable(int p_idx, bool p_checkable);
void set_item_as_radio_checkable(int p_idx, bool p_radio_checkable);
void set_item_tooltip(int p_idx, const String &p_tooltip);
- void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false);
+ void set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global = false);
void set_item_h_offset(int p_idx, int p_offset);
void set_item_multistate(int p_idx, int p_state);
void toggle_item_multistate(int p_idx);
@@ -174,7 +189,7 @@ public:
bool is_item_radio_checkable(int p_idx) const;
bool is_item_shortcut_disabled(int p_idx) const;
String get_item_tooltip(int p_idx) const;
- Ref<ShortCut> get_item_shortcut(int p_idx) const;
+ Ref<Shortcut> get_item_shortcut(int p_idx) const;
int get_item_state(int p_idx) const;
int get_current_index() const;
diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h
index 77c82aa780..a5401f7eaa 100644
--- a/scene/gui/rich_text_effect.h
+++ b/scene/gui/rich_text_effect.h
@@ -59,7 +59,7 @@ public:
bool visibility;
Point2 offset;
Color color;
- CharType character;
+ char32_t character;
float elapsed_time;
Dictionary environment;
@@ -79,7 +79,7 @@ public:
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; }
+ void set_character(int p_char) { character = (char32_t)p_char; }
Dictionary get_environment() { return environment; }
void set_environment(Dictionary p_environment) { environment = p_environment; }
};
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 29337e20f3..e8acac172c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -256,7 +256,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
lh = line < l.height_caches.size() ? l.height_caches[line] : 1; \
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; \
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1; \
- if ((p_mode == PROCESS_DRAW) && (align != ALIGN_FILL)) { \
+ if (align != ALIGN_FILL) { \
if (line < l.offset_caches.size()) { \
wofs = l.offset_caches[line]; \
} \
@@ -354,8 +354,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
font = p_base_font;
}
- const CharType *c = text->text.c_str();
- const CharType *cf = c;
+ const char32_t *c = text->text.get_data();
+ const char32_t *cf = c;
int ascent = font->get_ascent();
int descent = font->get_descent();
@@ -461,7 +461,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
bool selected = false;
Color fx_color = Color(color);
Point2 fx_offset;
- CharType fx_char = c[i];
+ char32_t fx_char = c[i];
if (selection.active) {
int cofs = (&c[i]) - cf;
@@ -2529,9 +2529,9 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
return false;
}
-void RichTextLabel::selection_copy() {
+String RichTextLabel::get_selected_text() {
if (!selection.active || !selection.enabled) {
- return;
+ return "";
}
String text;
@@ -2561,6 +2561,12 @@ void RichTextLabel::selection_copy() {
item = _get_next_item(item, true);
}
+ return text;
+}
+
+void RichTextLabel::selection_copy() {
+ String text = get_selected_text();
+
if (text != "") {
DisplayServer::get_singleton()->clipboard_set(text);
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 2bda7c7fce..c5ed1cb3ef 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -475,6 +475,7 @@ public:
void set_selection_enabled(bool p_enabled);
bool is_selection_enabled() const;
+ String get_selected_text();
void selection_copy();
Error parse_bbcode(const String &p_bbcode);
diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp
index 9f5b9c40c2..f8c7bc44a7 100644
--- a/scene/gui/shortcut.cpp
+++ b/scene/gui/shortcut.cpp
@@ -32,20 +32,20 @@
#include "core/os/keyboard.h"
-void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
+void Shortcut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
shortcut = p_shortcut;
emit_changed();
}
-Ref<InputEvent> ShortCut::get_shortcut() const {
+Ref<InputEvent> Shortcut::get_shortcut() const {
return shortcut;
}
-bool ShortCut::is_shortcut(const Ref<InputEvent> &p_event) const {
+bool Shortcut::is_shortcut(const Ref<InputEvent> &p_event) const {
return shortcut.is_valid() && shortcut->shortcut_match(p_event);
}
-String ShortCut::get_as_text() const {
+String Shortcut::get_as_text() const {
if (shortcut.is_valid()) {
return shortcut->as_text();
} else {
@@ -53,21 +53,21 @@ String ShortCut::get_as_text() const {
}
}
-bool ShortCut::is_valid() const {
+bool Shortcut::is_valid() const {
return shortcut.is_valid();
}
-void ShortCut::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &ShortCut::set_shortcut);
- ClassDB::bind_method(D_METHOD("get_shortcut"), &ShortCut::get_shortcut);
+void Shortcut::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &Shortcut::set_shortcut);
+ ClassDB::bind_method(D_METHOD("get_shortcut"), &Shortcut::get_shortcut);
- ClassDB::bind_method(D_METHOD("is_valid"), &ShortCut::is_valid);
+ ClassDB::bind_method(D_METHOD("is_valid"), &Shortcut::is_valid);
- ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &ShortCut::is_shortcut);
- ClassDB::bind_method(D_METHOD("get_as_text"), &ShortCut::get_as_text);
+ ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &Shortcut::is_shortcut);
+ ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_shortcut", "get_shortcut");
}
-ShortCut::ShortCut() {
+Shortcut::Shortcut() {
}
diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h
index 063d4e43dc..0d7809e5cf 100644
--- a/scene/gui/shortcut.h
+++ b/scene/gui/shortcut.h
@@ -34,8 +34,8 @@
#include "core/input/input_event.h"
#include "core/resource.h"
-class ShortCut : public Resource {
- GDCLASS(ShortCut, Resource);
+class Shortcut : public Resource {
+ GDCLASS(Shortcut, Resource);
Ref<InputEvent> shortcut;
@@ -50,7 +50,7 @@ public:
String get_as_text() const;
- ShortCut();
+ Shortcut();
};
#endif // SHORTCUT_H
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 8f71aa7cab..d47f771d1d 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -388,6 +388,7 @@ void Tabs::set_current_tab(int p_current) {
}
ERR_FAIL_INDEX(p_current, get_tab_count());
+ previous = current;
current = p_current;
_change_notify("current_tab");
@@ -401,6 +402,10 @@ int Tabs::get_current_tab() const {
return current;
}
+int Tabs::get_previous_tab() const {
+ return previous;
+}
+
int Tabs::get_hovered_tab() const {
return hover;
}
@@ -588,6 +593,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
void Tabs::clear_tabs() {
tabs.clear();
current = 0;
+ previous = 0;
call_deferred("_update_hover");
update();
}
@@ -605,6 +611,7 @@ void Tabs::remove_tab(int p_idx) {
if (current < 0) {
current = 0;
+ previous = 0;
}
if (current >= tabs.size()) {
current = tabs.size() - 1;
@@ -917,6 +924,7 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab);
ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab);
+ ClassDB::bind_method(D_METHOD("get_previous_tab"), &Tabs::get_previous_tab);
ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &Tabs::set_tab_title);
ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &Tabs::get_tab_title);
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &Tabs::set_tab_icon);
@@ -970,6 +978,7 @@ void Tabs::_bind_methods() {
Tabs::Tabs() {
current = 0;
+ previous = 0;
tab_align = ALIGN_CENTER;
rb_hover = -1;
rb_pressing = false;
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 8d7f1aa37d..b94c4a37a1 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -77,6 +77,7 @@ private:
bool missing_right;
Vector<Tab> tabs;
int current;
+ int previous;
int _get_top_margin() const;
TabAlign tab_align;
int rb_hover;
@@ -138,6 +139,7 @@ public:
int get_tab_count() const;
void set_current_tab(int p_current);
int get_current_tab() const;
+ int get_previous_tab() const;
int get_hovered_tab() const;
int get_tab_offset() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d6d8e74748..957e1c11c7 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -44,23 +44,23 @@
#define TAB_PIXELS
-inline bool _is_symbol(CharType c) {
+inline bool _is_symbol(char32_t c) {
return is_symbol(c);
}
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return !is_symbol(c);
}
-static bool _is_whitespace(CharType c) {
+static bool _is_whitespace(char32_t c) {
return c == '\t' || c == ' ';
}
-static bool _is_char(CharType c) {
+static bool _is_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
-static bool _is_pair_right_symbol(CharType c) {
+static bool _is_pair_right_symbol(char32_t c) {
return c == '"' ||
c == '\'' ||
c == ')' ||
@@ -68,7 +68,7 @@ static bool _is_pair_right_symbol(CharType c) {
c == '}';
}
-static bool _is_pair_left_symbol(CharType c) {
+static bool _is_pair_left_symbol(char32_t c) {
return c == '"' ||
c == '\'' ||
c == '(' ||
@@ -76,11 +76,11 @@ static bool _is_pair_left_symbol(CharType c) {
c == '{';
}
-static bool _is_pair_symbol(CharType c) {
+static bool _is_pair_symbol(char32_t c) {
return _is_pair_left_symbol(c) || _is_pair_right_symbol(c);
}
-static CharType _get_right_pair_symbol(CharType c) {
+static char32_t _get_right_pair_symbol(char32_t c) {
if (c == '"') {
return '"';
}
@@ -107,6 +107,8 @@ static int _find_first_non_whitespace_column_of_line(const String &line) {
return left;
}
+///////////////////////////////////////////////////////////////////////////////
+
void TextEdit::Text::set_font(const Ref<Font> &p_font) {
font = p_font;
}
@@ -119,7 +121,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
int w = 0;
int len = text[p_line].data.length();
- const CharType *str = text[p_line].data.c_str();
+ const char32_t *str = text[p_line].data.get_data();
// Update width.
@@ -165,12 +167,6 @@ void TextEdit::Text::clear_wrap_cache() {
}
}
-void TextEdit::Text::clear_info_icons() {
- for (int i = 0; i < text.size(); i++) {
- text.write[i].has_info = false;
- }
-}
-
void TextEdit::Text::clear() {
text.clear();
insert(0, "");
@@ -198,12 +194,9 @@ void TextEdit::Text::set(int p_line, const String &p_text) {
void TextEdit::Text::insert(int p_at, const String &p_text) {
Line line;
+ line.gutters.resize(gutter_count);
line.marked = false;
- line.safe = false;
- line.breakpoint = false;
- line.bookmark = false;
line.hidden = false;
- line.has_info = false;
line.width_cache = -1;
line.wrap_amount_cache = -1;
line.data = p_text;
@@ -214,7 +207,7 @@ void TextEdit::Text::remove(int p_at) {
text.remove(p_at);
}
-int TextEdit::Text::get_char_width(CharType c, CharType next_c, int px) const {
+int TextEdit::Text::get_char_width(char32_t c, char32_t next_c, int px) const {
int tab_w = font->get_char_size(' ').width * indent_size;
int w = 0;
@@ -231,6 +224,32 @@ int TextEdit::Text::get_char_width(CharType c, CharType next_c, int px) const {
return w;
}
+void TextEdit::Text::add_gutter(int p_at) {
+ for (int i = 0; i < text.size(); i++) {
+ if (p_at < 0 || p_at > gutter_count) {
+ text.write[i].gutters.push_back(Gutter());
+ } else {
+ text.write[i].gutters.insert(p_at, Gutter());
+ }
+ }
+ gutter_count++;
+}
+
+void TextEdit::Text::remove_gutter(int p_gutter) {
+ for (int i = 0; i < text.size(); i++) {
+ text.write[i].gutters.remove(p_gutter);
+ }
+ gutter_count--;
+}
+
+void TextEdit::Text::move_gutters(int p_from_line, int p_to_line) {
+ text.write[p_to_line].gutters = text[p_from_line].gutters;
+ text.write[p_from_line].gutters.clear();
+ text.write[p_from_line].gutters.resize(gutter_count);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
void TextEdit::_update_scrollbars() {
Size2 size = get_size();
Size2 hmin = h_scroll->get_combined_minimum_size();
@@ -249,23 +268,7 @@ void TextEdit::_update_scrollbars() {
}
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
- int total_width = text.get_max_width(true) + vmin.x;
-
- if (line_numbers) {
- total_width += cache.line_number_w;
- }
-
- if (draw_breakpoint_gutter || draw_bookmark_gutter) {
- total_width += cache.breakpoint_gutter_width;
- }
-
- if (draw_info_gutter) {
- total_width += cache.info_gutter_width;
- }
-
- if (draw_fold_gutter) {
- total_width += cache.fold_gutter_width;
- }
+ int total_width = text.get_max_width(true) + vmin.x + gutters_width + gutter_padding;
if (draw_minimap) {
total_width += cache.minimap_width;
@@ -557,54 +560,16 @@ void TextEdit::_notification(int p_what) {
draw_caret = false;
}
- if (draw_breakpoint_gutter || draw_bookmark_gutter) {
- breakpoint_gutter_width = (get_row_height() * 55) / 100;
- cache.breakpoint_gutter_width = breakpoint_gutter_width;
- } else {
- cache.breakpoint_gutter_width = 0;
- }
-
- if (draw_info_gutter) {
- info_gutter_width = (get_row_height());
- cache.info_gutter_width = info_gutter_width;
- } else {
- cache.info_gutter_width = 0;
- }
-
- if (draw_fold_gutter) {
- fold_gutter_width = (get_row_height() * 55) / 100;
- cache.fold_gutter_width = fold_gutter_width;
- } else {
- cache.fold_gutter_width = 0;
- }
-
cache.minimap_width = 0;
if (draw_minimap) {
cache.minimap_width = minimap_width;
}
- int line_number_char_count = 0;
-
- {
- int lc = text.size();
- cache.line_number_w = 0;
- while (lc) {
- cache.line_number_w += 1;
- lc /= 10;
- };
-
- if (line_numbers) {
- line_number_char_count = cache.line_number_w;
- cache.line_number_w = (cache.line_number_w + 1) * cache.font->get_char_size('0').width;
- } else {
- cache.line_number_w = 0;
- }
- }
_update_scrollbars();
RID ci = get_canvas_item();
RenderingServer::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_beg = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding;
int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT) - cache.minimap_width;
// Let's do it easy for now.
@@ -654,8 +619,8 @@ 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.
- CharType c = text[cursor.line][cursor.column];
- CharType closec = 0;
+ char32_t c = text[cursor.line][cursor.column];
+ char32_t closec = 0;
if (c == '[') {
closec = ']';
@@ -671,10 +636,10 @@ void TextEdit::_notification(int p_what) {
for (int i = cursor.line; i < text.size(); i++) {
int from = i == cursor.line ? cursor.column + 1 : 0;
for (int j = from; j < text[i].length(); j++) {
- CharType cc = text[i][j];
+ char32_t cc = text[i][j];
// Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
- CharType quotation = cc;
+ char32_t quotation = cc;
do {
j++;
if (!(j < text[i].length())) {
@@ -720,8 +685,8 @@ void TextEdit::_notification(int p_what) {
}
if (cursor.column > 0) {
- CharType c = text[cursor.line][cursor.column - 1];
- CharType closec = 0;
+ char32_t c = text[cursor.line][cursor.column - 1];
+ char32_t closec = 0;
if (c == ']') {
closec = '[';
@@ -737,10 +702,10 @@ void TextEdit::_notification(int p_what) {
for (int i = cursor.line; i >= 0; i--) {
int from = i == cursor.line ? cursor.column - 2 : text[i].length() - 1;
for (int j = from; j >= 0; j--) {
- CharType cc = text[i][j];
+ char32_t cc = text[i][j];
// Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
- CharType quotation = cc;
+ char32_t quotation = cc;
do {
j--;
if (!(j >= 0)) {
@@ -795,8 +760,6 @@ void TextEdit::_notification(int p_what) {
// 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" : " ";
-
int cursor_wrap_index = get_cursor_wrap_index();
FontDrawer drawer(cache.font, Color(1, 1, 1));
@@ -1053,103 +1016,52 @@ void TextEdit::_notification(int p_what) {
if (line_wrap_index == 0) {
// 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
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y + get_row_height() - EDSCALE, xmargin_end - xmargin_beg, EDSCALE), cache.breakpoint_color);
-#else
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, get_row_height()), cache.breakpoint_color);
-#endif
- }
+ int gutter_offset = cache.style_normal->get_margin(MARGIN_LEFT);
+ for (int g = 0; g < gutters.size(); g++) {
+ const GutterInfo gutter = gutters[g];
- // Draw bookmark marker.
- if (text.is_bookmark(line)) {
- if (draw_bookmark_gutter) {
- int vertical_gap = (get_row_height() * 40) / 100;
- int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
- int marker_radius = get_row_height() - (vertical_gap * 2);
- RenderingServer::get_singleton()->canvas_item_add_circle(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2 + marker_radius / 2, ofs_y + vertical_gap + marker_radius / 2), marker_radius, Color(cache.bookmark_color.r, cache.bookmark_color.g, cache.bookmark_color.b));
+ if (!gutter.draw || gutter.width <= 0) {
+ continue;
}
- }
- // 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.
- RenderingServer::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.
- 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<Texture2D> info_icon = text.get_info_icon(line);
- // 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;
- }
- if (icon_size.height > get_row_height() - horizontal_gap) {
- icon_size.height = get_row_height() - horizontal_gap;
- }
+ switch (gutter.type) {
+ case GUTTER_TYPE_STRING: {
+ const String &text = get_line_gutter_text(line, g);
+ if (text == "") {
+ break;
+ }
- Size2i icon_pos;
- int xofs = horizontal_gap - (info_icon->get_width() / 4);
- int yofs = vertical_gap - (info_icon->get_height() / 4);
- icon_pos.x = gutter_left + xofs + ofs_x;
- icon_pos.y = ofs_y + yofs;
+ int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
+ cache.font->draw(ci, Point2(gutter_offset + ofs_x, yofs + cache.font->get_ascent()), text, get_line_gutter_item_color(line, g));
+ } break;
+ case GUTTER_TPYE_ICON: {
+ const Ref<Texture2D> icon = get_line_gutter_icon(line, g);
+ if (icon.is_null()) {
+ break;
+ }
- draw_texture_rect(info_icon, Rect2(icon_pos, icon_size));
- }
+ Rect2i gutter_rect = Rect2i(Point2i(gutter_offset, ofs_y), Size2i(gutter.width, get_row_height()));
- // Draw execution marker.
- if (executing_line == line) {
- if (draw_breakpoint_gutter) {
- int icon_extra_size = 4;
- 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) + icon_extra_size;
- int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2) + icon_extra_size;
- cache.executing_icon->draw_rect(ci, Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2 - icon_extra_size / 2, ofs_y + vertical_gap - icon_extra_size / 2, marker_width, marker_height), false, Color(cache.executing_line_color.r, cache.executing_line_color.g, cache.executing_line_color.b));
- } else {
-#ifdef TOOLS_ENABLED
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y + get_row_height() - EDSCALE, xmargin_end - xmargin_beg, EDSCALE), cache.executing_line_color);
-#else
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, get_row_height()), cache.executing_line_color);
-#endif
- }
- }
+ int horizontal_padding = gutter_rect.size.x / 6;
+ int vertical_padding = gutter_rect.size.y / 6;
- // 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;
- if (is_folded(line)) {
- int xofs = horizontal_gap - (cache.can_fold_icon->get_width()) / 2;
- int yofs = (get_row_height() - cache.folded_icon->get_height()) / 2;
- cache.folded_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), cache.code_folding_color);
- } else if (can_fold(line)) {
- int xofs = -cache.can_fold_icon->get_width() / 2 - horizontal_gap + 3;
- int yofs = (get_row_height() - cache.can_fold_icon->get_height()) / 2;
- cache.can_fold_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), cache.code_folding_color);
- }
- }
+ gutter_rect.position += Point2(horizontal_padding, vertical_padding);
+ gutter_rect.size -= Point2(horizontal_padding, vertical_padding) * 2;
- // 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);
- while (fc.length() < line_number_char_count) {
- fc = line_num_padding + fc;
+ icon->draw_rect(ci, gutter_rect, false, get_line_gutter_item_color(line, g));
+ } break;
+ case GUTTER_TPYE_CUSTOM: {
+ if (gutter.custom_draw_obj.is_valid()) {
+ Object *cdo = ObjectDB::get_instance(gutter.custom_draw_obj);
+ if (cdo) {
+ Rect2i gutter_rect = Rect2i(Point2i(gutter_offset, ofs_y), Size2i(gutter.width, get_row_height()));
+ cdo->call(gutter.custom_draw_callback, line, g, Rect2(gutter_rect));
+ }
+ }
+ } break;
}
- cache.font->draw(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + cache.info_gutter_width + ofs_x, yofs + cache.font->get_ascent()), fc, text.is_safe(line) ? cache.safe_line_number_color : cache.line_number_color);
+ gutter_offset += gutter.width;
}
}
@@ -1303,8 +1215,8 @@ void TextEdit::_notification(int p_what) {
break;
}
- CharType cchar = ime_text[ofs];
- CharType next = ime_text[ofs + 1];
+ char32_t cchar = ime_text[ofs];
+ char32_t next = ime_text[ofs + 1];
int im_char_width = cache.font->get_char_size(cchar, next).width;
if ((char_ofs + char_margin + im_char_width) >= xmargin_end) {
@@ -1399,8 +1311,8 @@ void TextEdit::_notification(int p_what) {
break;
}
- CharType cchar = ime_text[ofs];
- CharType next = ime_text[ofs + 1];
+ char32_t cchar = ime_text[ofs];
+ char32_t next = ime_text[ofs + 1];
int im_char_width = cache.font->get_char_size(cchar, next).width;
if ((char_ofs + char_margin + im_char_width) >= xmargin_end) {
@@ -1661,12 +1573,12 @@ void TextEdit::_notification(int p_what) {
}
}
-void TextEdit::_consume_pair_symbol(CharType ch) {
+void TextEdit::_consume_pair_symbol(char32_t ch) {
int cursor_position_to_move = cursor_get_column() + 1;
- CharType ch_single[2] = { ch, 0 };
- CharType ch_single_pair[2] = { _get_right_pair_symbol(ch), 0 };
- CharType ch_pair[3] = { ch, _get_right_pair_symbol(ch), 0 };
+ char32_t ch_single[2] = { ch, 0 };
+ char32_t ch_single_pair[2] = { _get_right_pair_symbol(ch), 0 };
+ char32_t ch_pair[3] = { ch, _get_right_pair_symbol(ch), 0 };
if (is_selection_active()) {
int new_column, new_line;
@@ -1771,8 +1683,8 @@ void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column
bool remove_right_symbol = false;
if (cursor.column < text[cursor.line].length() && cursor.column > 0) {
- CharType left_char = text[cursor.line][cursor.column - 1];
- CharType right_char = text[cursor.line][cursor.column];
+ char32_t left_char = text[cursor.line][cursor.column - 1];
+ char32_t right_char = text[cursor.line][cursor.column];
if (right_char == _get_right_pair_symbol(left_char)) {
remove_right_symbol = true;
@@ -1797,18 +1709,34 @@ void TextEdit::backspace_at_cursor() {
int prev_line = cursor.column ? cursor.line : cursor.line - 1;
int prev_column = cursor.column ? (cursor.column - 1) : (text[cursor.line - 1].length());
- if (is_line_hidden(cursor.line)) {
- set_line_as_hidden(prev_line, true);
- }
- if (is_line_set_as_breakpoint(cursor.line)) {
- if (!text.is_breakpoint(prev_line)) {
- emit_signal("breakpoint_toggled", prev_line);
+ if (cursor.line != prev_line) {
+ for (int i = 0; i < gutters.size(); i++) {
+ if (!gutters[i].overwritable) {
+ continue;
+ }
+
+ if (text.get_line_gutter_text(cursor.line, i) != "") {
+ text.set_line_gutter_text(prev_line, i, text.get_line_gutter_text(cursor.line, i));
+ text.set_line_gutter_item_color(prev_line, i, text.get_line_gutter_item_color(cursor.line, i));
+ }
+
+ if (text.get_line_gutter_icon(cursor.line, i).is_valid()) {
+ text.set_line_gutter_icon(prev_line, i, text.get_line_gutter_icon(cursor.line, i));
+ text.set_line_gutter_item_color(prev_line, i, text.get_line_gutter_item_color(cursor.line, i));
+ }
+
+ if (text.get_line_gutter_metadata(cursor.line, i) != "") {
+ text.set_line_gutter_metadata(prev_line, i, text.get_line_gutter_metadata(cursor.line, i));
+ }
+
+ if (text.is_line_gutter_clickable(cursor.line, i)) {
+ text.set_line_gutter_clickable(prev_line, i, true);
+ }
}
- set_line_as_breakpoint(prev_line, true);
}
- if (text.has_info_icon(cursor.line)) {
- set_line_info_icon(prev_line, text.get_info_icon(cursor.line), text.get_info(cursor.line));
+ if (is_line_hidden(cursor.line)) {
+ set_line_as_hidden(prev_line, true);
}
if (auto_brace_completion_enabled &&
@@ -1998,7 +1926,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
row = text.size() - 1;
col = text[row].size();
} else {
- int colx = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width);
+ int colx = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding);
colx += cursor.x_ofs;
col = get_char_pos_for_line(colx, row, wrap_index);
if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) {
@@ -2043,7 +1971,7 @@ Vector2i TextEdit::_get_cursor_pixel_pos() {
// 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 x = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding - cursor.x_ofs;
int ix = 0;
while (ix < rows2[0].size() && ix < cursor.column) {
if (cache.font != nullptr) {
@@ -2178,45 +2106,24 @@ 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);
- // 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) {
- set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row));
- emit_signal("breakpoint_toggled", row);
- return;
+ int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
+ for (int i = 0; i < gutters.size(); i++) {
+ if (!gutters[i].draw || gutters[i].width <= 0) {
+ continue;
}
- }
- // 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;
- if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.info_gutter_width - 3) {
- emit_signal("info_clicked", row, text.get_info(row));
+ if (mb->get_position().x > left_margin && mb->get_position().x <= (left_margin + gutters[i].width) - 3) {
+ emit_signal("gutter_clicked", row, i);
return;
}
- }
- // Toggle fold on gutter click if can.
- if (draw_fold_gutter) {
- int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
- int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w + cache.info_gutter_width;
- if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.fold_gutter_width - 3) {
- if (is_folded(row)) {
- unfold_line(row);
- } else if (can_fold(row)) {
- fold_line(row);
- }
- return;
- }
+ left_margin += gutters[i].width;
}
// 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;
- if (mb->get_position().x > line_width - 3 && mb->get_position().x <= line_width + cache.folded_eol_icon->get_width() + 3) {
+ left_margin += gutter_padding + text.get_line_width(row) - cursor.x_ofs;
+ if (mb->get_position().x > left_margin && mb->get_position().x <= left_margin + cache.folded_eol_icon->get_width() + 3) {
unfold_line(row);
return;
}
@@ -2540,7 +2447,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (k->get_unicode() > 32) {
_reset_caret_blink_timer();
- const CharType chr[2] = { (CharType)k->get_unicode(), 0 };
+ const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 };
if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]);
} else {
@@ -2784,7 +2691,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
// No need to move the brace below if we are not taking the text with us.
- char closing_char = _get_right_pair_symbol(indent_char);
+ char32_t closing_char = _get_right_pair_symbol(indent_char);
if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) {
brace_indent = true;
ins += "\n" + ins.substr(1, ins.length() - 2);
@@ -3312,7 +3219,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// 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];
+ char32_t c = text[cursor.line][current_line_whitespace_len];
if (c != '\t' && c != ' ') {
break;
}
@@ -3458,7 +3365,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int current_line_whitespace_len = 0;
while (current_line_whitespace_len < text[cursor.line].length()) {
- CharType c = text[cursor.line][current_line_whitespace_len];
+ char32_t c = text[cursor.line][current_line_whitespace_len];
if (c != '\t' && c != ' ')
break;
current_line_whitespace_len++;
@@ -3624,7 +3531,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- const CharType chr[2] = { (CharType)k->get_unicode(), 0 };
+ const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 };
if (completion_hint != "" && k->get_unicode() == ')') {
completion_hint = "";
@@ -3775,30 +3682,15 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
Vector<String> substrings = p_text.replace("\r", "").split("\n");
- /* 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";
- int i = p_line + !shift_first_line;
- int lines = substrings.size() - 1;
- for (; i < text.size(); i++) {
- if (text.is_breakpoint(i)) {
- if ((i - lines < p_line || !text.is_breakpoint(i - lines)) || (i - lines == p_line && !shift_first_line)) {
- emit_signal("breakpoint_toggled", i);
- }
- if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
- emit_signal("breakpoint_toggled", i + lines);
- }
- }
- }
-
- /* STEP 3: Add spaces if the char is greater than the end of the line. */
+ /* STEP 2: 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 3: 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());
@@ -3818,15 +3710,10 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
if (shift_first_line) {
- text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
+ text.move_gutters(p_line, p_line + 1);
text.set_hidden(p_line + 1, text.is_hidden(p_line));
- if (text.has_info_icon(p_line)) {
- text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
- }
- text.set_breakpoint(p_line, false);
text.set_hidden(p_line, false);
- text.set_info_icon(p_line, nullptr, "");
}
text.set_line_wrap_amount(p_line, -1);
@@ -3840,7 +3727,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
text_changed_dirty = true;
}
- emit_signal("line_edited_from", p_line);
+ emit_signal("lines_edited_from", p_line, r_end_line);
}
String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) const {
@@ -3877,19 +3764,6 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
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());
- int lines = p_to_line - p_from_line;
-
- for (int i = p_from_line + 1; i < text.size(); i++) {
- if (text.is_breakpoint(i)) {
- if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
- emit_signal("breakpoint_toggled", i);
- }
- if (i > p_to_line && (i - lines < 0 || !text.is_breakpoint(i - lines))) {
- emit_signal("breakpoint_toggled", i - lines);
- }
- }
- }
-
for (int i = p_from_line; i < p_to_line; i++) {
text.remove(p_from_line + 1);
}
@@ -3903,7 +3777,7 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
}
text_changed_dirty = true;
}
- emit_signal("line_edited_from", p_from_line);
+ emit_signal("lines_edited_from", p_to_line, p_from_line);
}
void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r_end_line, int *r_end_char) {
@@ -4097,7 +3971,7 @@ 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 - cache.minimap_width - wrap_right_offset;
+ wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.minimap_width - wrap_right_offset;
update_cursor_wrap_offset();
text.clear_wrap_cache();
@@ -4132,7 +4006,7 @@ void TextEdit::adjust_viewport_to_cursor() {
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 - cache.minimap_width;
+ int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.minimap_width;
if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
}
@@ -4167,7 +4041,7 @@ void TextEdit::center_viewport_to_cursor() {
}
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 - cache.minimap_width;
+ int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.minimap_width;
if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
}
@@ -4251,7 +4125,7 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
while (col < line_text.length()) {
- CharType c = line_text[col];
+ char32_t c = line_text[col];
int w = text.get_char_width(c, line_text[col + 1], px + word_px);
int indent_ofs = (cur_wrap_index != 0 ? tab_offset_px : 0);
@@ -4614,54 +4488,41 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_POINTING_HAND;
}
- int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
if ((completion_active && completion_rect.has_point(p_pos))) {
return CURSOR_ARROW;
}
- if (p_pos.x < gutter) {
- int row, col;
- _get_mouse_pos(p_pos, row, col);
- int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
- // 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;
- }
+ int row, col;
+ _get_mouse_pos(p_pos, row, col);
- // 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)) {
- return CURSOR_POINTING_HAND;
+ int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
+ int gutter = left_margin + gutters_width;
+ if (p_pos.x < gutter) {
+ for (int i = 0; i < gutters.size(); i++) {
+ if (!gutters[i].draw) {
+ continue;
}
- return CURSOR_ARROW;
- }
- // 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;
- } else {
- return CURSOR_ARROW;
+ if (p_pos.x > left_margin && p_pos.x <= (left_margin + gutters[i].width) - 3) {
+ if (gutters[i].clickable || is_line_gutter_clickable(row, i)) {
+ return CURSOR_POINTING_HAND;
+ }
}
+ left_margin += gutters[i].width;
}
+ return CURSOR_ARROW;
+ }
+ 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;
- } 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.
- 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;
- if (p_pos.x > line_width - 3 && p_pos.x <= line_width + cache.folded_eol_icon->get_width() + 3) {
- return CURSOR_POINTING_HAND;
- }
+ }
+
+ // EOL fold icon.
+ if (is_folded(row)) {
+ gutter += gutter_padding + text.get_line_width(row) - cursor.x_ofs;
+ if (p_pos.x > gutter - 3 && p_pos.x <= gutter + cache.folded_eol_icon->get_width() + 3) {
+ return CURSOR_POINTING_HAND;
}
}
@@ -4861,8 +4722,6 @@ void TextEdit::_update_caches() {
cache.font = get_theme_font("font");
cache.caret_color = get_theme_color("caret_color");
cache.caret_background_color = get_theme_color("caret_background_color");
- cache.line_number_color = get_theme_color("line_number_color");
- cache.safe_line_number_color = get_theme_color("safe_line_number_color");
cache.font_color = get_theme_color("font_color");
cache.font_color_selected = get_theme_color("font_color_selected");
cache.font_color_readonly = get_theme_color("font_color_readonly");
@@ -4870,9 +4729,6 @@ void TextEdit::_update_caches() {
cache.mark_color = get_theme_color("mark_color");
cache.current_line_color = get_theme_color("current_line_color");
cache.line_length_guideline_color = get_theme_color("line_length_guideline_color");
- cache.bookmark_color = get_theme_color("bookmark_color");
- cache.breakpoint_color = get_theme_color("breakpoint_color");
- cache.executing_line_color = get_theme_color("executing_line_color");
cache.code_folding_color = get_theme_color("code_folding_color");
cache.brace_mismatch_color = get_theme_color("brace_mismatch_color");
cache.word_highlighted_color = get_theme_color("word_highlighted_color");
@@ -4887,10 +4743,7 @@ void TextEdit::_update_caches() {
cache.row_height = cache.font->get_height() + cache.line_spacing;
cache.tab_icon = get_theme_icon("tab");
cache.space_icon = get_theme_icon("space");
- cache.folded_icon = get_theme_icon("folded");
- cache.can_fold_icon = get_theme_icon("fold");
cache.folded_eol_icon = get_theme_icon("GuiEllipsis", "EditorIcons");
- cache.executing_icon = get_theme_icon("MainPlay", "EditorIcons");
text.set_font(cache.font);
text.clear_width_cache();
@@ -4899,6 +4752,7 @@ void TextEdit::_update_caches() {
}
}
+/* Syntax Highlighting. */
Ref<SyntaxHighlighter> TextEdit::get_syntax_highlighter() {
return syntax_highlighter;
}
@@ -4911,6 +4765,187 @@ void TextEdit::set_syntax_highlighter(Ref<SyntaxHighlighter> p_syntax_highlighte
update();
}
+/* Gutters. */
+void TextEdit::_update_gutter_width() {
+ gutters_width = 0;
+ for (int i = 0; i < gutters.size(); i++) {
+ if (gutters[i].draw) {
+ gutters_width += gutters[i].width;
+ }
+ }
+ if (gutters_width > 0) {
+ gutter_padding = 2;
+ }
+ update();
+}
+
+void TextEdit::add_gutter(int p_at) {
+ if (p_at < 0 || p_at > gutters.size()) {
+ gutters.push_back(GutterInfo());
+ } else {
+ gutters.insert(p_at, GutterInfo());
+ }
+
+ for (int i = 0; i < text.size() + 1; i++) {
+ text.add_gutter(p_at);
+ }
+ emit_signal("gutter_added");
+ update();
+}
+
+void TextEdit::remove_gutter(int p_gutter) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ gutters.remove(p_gutter);
+
+ for (int i = 0; i < text.size() + 1; i++) {
+ text.remove_gutter(p_gutter);
+ }
+ emit_signal("gutter_removed");
+ update();
+}
+
+int TextEdit::get_gutter_count() const {
+ return gutters.size();
+}
+
+void TextEdit::set_gutter_name(int p_gutter, const String &p_name) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].name = p_name;
+}
+
+String TextEdit::get_gutter_name(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), "");
+ return gutters[p_gutter].name;
+}
+
+void TextEdit::set_gutter_type(int p_gutter, GutterType p_type) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].type = p_type;
+ update();
+}
+
+TextEdit::GutterType TextEdit::get_gutter_type(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), GUTTER_TYPE_STRING);
+ return gutters[p_gutter].type;
+}
+
+void TextEdit::set_gutter_width(int p_gutter, int p_width) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].width = p_width;
+ _update_gutter_width();
+}
+
+int TextEdit::get_gutter_width(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), -1);
+ return gutters[p_gutter].width;
+}
+
+void TextEdit::set_gutter_draw(int p_gutter, bool p_draw) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].draw = p_draw;
+ _update_gutter_width();
+}
+
+bool TextEdit::is_gutter_drawn(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), false);
+ return gutters[p_gutter].draw;
+}
+
+void TextEdit::set_gutter_clickable(int p_gutter, bool p_clickable) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].clickable = p_clickable;
+ update();
+}
+
+bool TextEdit::is_gutter_clickable(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), false);
+ return gutters[p_gutter].clickable;
+}
+
+void TextEdit::set_gutter_overwritable(int p_gutter, bool p_overwritable) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ gutters.write[p_gutter].overwritable = p_overwritable;
+}
+
+bool TextEdit::is_gutter_overwritable(int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), false);
+ return gutters[p_gutter].overwritable;
+}
+
+void TextEdit::set_gutter_custom_draw(int p_gutter, Object *p_object, const StringName &p_callback) {
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ ERR_FAIL_NULL(p_object);
+
+ gutters.write[p_gutter].custom_draw_obj = p_object->get_instance_id();
+ gutters.write[p_gutter].custom_draw_callback = p_callback;
+ update();
+}
+
+// Line gutters.
+void TextEdit::set_line_gutter_metadata(int p_line, int p_gutter, const Variant &p_metadata) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ text.set_line_gutter_metadata(p_line, p_gutter, p_metadata);
+}
+
+Variant TextEdit::get_line_gutter_metadata(int p_line, int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_line, text.size(), "");
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), "");
+ return text.get_line_gutter_metadata(p_line, p_gutter);
+}
+
+void TextEdit::set_line_gutter_text(int p_line, int p_gutter, const String &p_text) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ text.set_line_gutter_text(p_line, p_gutter, p_text);
+ update();
+}
+
+String TextEdit::get_line_gutter_text(int p_line, int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_line, text.size(), "");
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), "");
+ return text.get_line_gutter_text(p_line, p_gutter);
+}
+
+void TextEdit::set_line_gutter_icon(int p_line, int p_gutter, Ref<Texture2D> p_icon) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ text.set_line_gutter_icon(p_line, p_gutter, p_icon);
+ update();
+}
+
+Ref<Texture2D> TextEdit::get_line_gutter_icon(int p_line, int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_line, text.size(), Ref<Texture2D>());
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), Ref<Texture2D>());
+ return text.get_line_gutter_icon(p_line, p_gutter);
+}
+
+void TextEdit::set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ text.set_line_gutter_item_color(p_line, p_gutter, p_color);
+ update();
+}
+
+Color TextEdit::get_line_gutter_item_color(int p_line, int p_gutter) {
+ ERR_FAIL_INDEX_V(p_line, text.size(), Color());
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), Color());
+ return text.get_line_gutter_item_color(p_line, p_gutter);
+}
+
+void TextEdit::set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable) {
+ ERR_FAIL_INDEX(p_line, text.size());
+ ERR_FAIL_INDEX(p_gutter, gutters.size());
+ text.set_line_gutter_clickable(p_line, p_gutter, p_clickable);
+}
+
+bool TextEdit::is_line_gutter_clickable(int p_line, int p_gutter) const {
+ ERR_FAIL_INDEX_V(p_line, text.size(), false);
+ ERR_FAIL_INDEX_V(p_gutter, gutters.size(), false);
+ return text.is_line_gutter_clickable(p_line, p_gutter);
+}
+
void TextEdit::add_keyword(const String &p_keyword) {
keywords.insert(p_keyword);
}
@@ -5341,106 +5376,6 @@ void TextEdit::set_line_as_marked(int p_line, bool p_marked) {
update();
}
-void TextEdit::set_line_as_safe(int p_line, bool p_safe) {
- ERR_FAIL_INDEX(p_line, text.size());
- text.set_safe(p_line, p_safe);
- update();
-}
-
-bool TextEdit::is_line_set_as_safe(int p_line) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), false);
- return text.is_safe(p_line);
-}
-
-void TextEdit::set_executing_line(int p_line) {
- ERR_FAIL_INDEX(p_line, text.size());
- executing_line = p_line;
- update();
-}
-
-void TextEdit::clear_executing_line() {
- executing_line = -1;
- update();
-}
-
-bool TextEdit::is_line_set_as_bookmark(int p_line) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), false);
- return text.is_bookmark(p_line);
-}
-
-void TextEdit::set_line_as_bookmark(int p_line, bool p_bookmark) {
- ERR_FAIL_INDEX(p_line, text.size());
- text.set_bookmark(p_line, p_bookmark);
- update();
-}
-
-void TextEdit::get_bookmarks(List<int> *p_bookmarks) const {
- for (int i = 0; i < text.size(); i++) {
- if (text.is_bookmark(i)) {
- p_bookmarks->push_back(i);
- }
- }
-}
-
-Array TextEdit::get_bookmarks_array() const {
- Array arr;
- for (int i = 0; i < text.size(); i++) {
- if (text.is_bookmark(i)) {
- arr.append(i);
- }
- }
- return arr;
-}
-
-bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
- ERR_FAIL_INDEX_V(p_line, text.size(), false);
- return text.is_breakpoint(p_line);
-}
-
-void TextEdit::set_line_as_breakpoint(int p_line, bool p_breakpoint) {
- ERR_FAIL_INDEX(p_line, text.size());
- text.set_breakpoint(p_line, p_breakpoint);
- update();
-}
-
-void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
- for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i)) {
- p_breakpoints->push_back(i);
- }
- }
-}
-
-Array TextEdit::get_breakpoints_array() const {
- Array arr;
- for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i)) {
- arr.append(i);
- }
- }
- return arr;
-}
-
-void TextEdit::remove_breakpoints() {
- for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i)) {
- /* Should "breakpoint_toggled" be fired when breakpoints are removed this way? */
- text.set_breakpoint(i, false);
- }
- }
-}
-
-void TextEdit::set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) {
- ERR_FAIL_INDEX(p_line, text.size());
- text.set_info_icon(p_line, p_icon, p_info);
- update();
-}
-
-void TextEdit::clear_info_icons() {
- text.clear_info_icons();
- update();
-}
-
void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) {
ERR_FAIL_INDEX(p_line, text.size());
if (is_hiding_enabled() || !p_hidden) {
@@ -6115,9 +6050,9 @@ void TextEdit::_confirm_completion() {
// When inserted into the middle of an existing string/method, don't add an unnecessary quote/bracket.
String line = text[cursor.line];
- CharType next_char = line[cursor.column];
- CharType last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1];
- CharType last_completion_char_display = completion_current.display[completion_current.display.length() - 1];
+ char32_t next_char = line[cursor.column];
+ char32_t last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1];
+ char32_t last_completion_char_display = completion_current.display[completion_current.display.length() - 1];
if ((last_completion_char == '"' || last_completion_char == '\'') && (last_completion_char == next_char || last_completion_char_display == next_char)) {
_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
@@ -6161,7 +6096,7 @@ void TextEdit::_cancel_completion() {
update();
}
-static bool _is_completable(CharType c) {
+static bool _is_completable(char32_t c) {
return !_is_symbol(c) || c == '"' || c == '\'';
}
@@ -6292,14 +6227,14 @@ void TextEdit::_update_completion_candidates() {
String display_lower = option.display.to_lower();
- const CharType *ssq = &s[0];
- const CharType *ssq_lower = &s_lower[0];
+ const char32_t *ssq = &s[0];
+ const char32_t *ssq_lower = &s_lower[0];
- const CharType *tgt = &option.display[0];
- const CharType *tgt_lower = &display_lower[0];
+ const char32_t *tgt = &option.display[0];
+ const char32_t *tgt_lower = &display_lower[0];
- const CharType *ssq_last_tgt = nullptr;
- const CharType *ssq_lower_last_tgt = nullptr;
+ const char32_t *ssq_last_tgt = nullptr;
+ const char32_t *ssq_lower_last_tgt = nullptr;
for (; *tgt; tgt++, tgt_lower++) {
if (*ssq == *tgt) {
@@ -6416,7 +6351,7 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
int beg, end;
if (select_word(s, col, beg, end)) {
bool inside_quotes = false;
- CharType selected_quote = '\0';
+ char32_t selected_quote = '\0';
int qbegin = 0, qend = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '"' || s[i] == '\'') {
@@ -6502,20 +6437,6 @@ void TextEdit::insert_at(const String &p_text, int at) {
}
}
-void TextEdit::set_show_line_numbers(bool p_show) {
- line_numbers = p_show;
- update();
-}
-
-void TextEdit::set_line_numbers_zero_padded(bool p_zero_padded) {
- line_numbers_zero_padded = p_zero_padded;
- update();
-}
-
-bool TextEdit::is_show_line_numbers_enabled() const {
- return line_numbers;
-}
-
void TextEdit::set_show_line_length_guidelines(bool p_show) {
line_length_guidelines = p_show;
update();
@@ -6531,69 +6452,6 @@ void TextEdit::set_line_length_guideline_hard_column(int p_column) {
update();
}
-void TextEdit::set_bookmark_gutter_enabled(bool p_draw) {
- draw_bookmark_gutter = p_draw;
- update();
-}
-
-bool TextEdit::is_bookmark_gutter_enabled() const {
- return draw_bookmark_gutter;
-}
-
-void TextEdit::set_breakpoint_gutter_enabled(bool p_draw) {
- draw_breakpoint_gutter = p_draw;
- update();
-}
-
-bool TextEdit::is_breakpoint_gutter_enabled() const {
- return draw_breakpoint_gutter;
-}
-
-void TextEdit::set_breakpoint_gutter_width(int p_gutter_width) {
- breakpoint_gutter_width = p_gutter_width;
- update();
-}
-
-int TextEdit::get_breakpoint_gutter_width() const {
- return cache.breakpoint_gutter_width;
-}
-
-void TextEdit::set_draw_fold_gutter(bool p_draw) {
- draw_fold_gutter = p_draw;
- update();
-}
-
-bool TextEdit::is_drawing_fold_gutter() const {
- return draw_fold_gutter;
-}
-
-void TextEdit::set_fold_gutter_width(int p_gutter_width) {
- fold_gutter_width = p_gutter_width;
- update();
-}
-
-int TextEdit::get_fold_gutter_width() const {
- return cache.fold_gutter_width;
-}
-
-void TextEdit::set_draw_info_gutter(bool p_draw) {
- draw_info_gutter = p_draw;
- update();
-}
-
-bool TextEdit::is_drawing_info_gutter() const {
- return draw_info_gutter;
-}
-
-void TextEdit::set_info_gutter_width(int p_gutter_width) {
- info_gutter_width = p_gutter_width;
- update();
-}
-
-int TextEdit::get_info_gutter_width() const {
- return info_gutter_width;
-}
-
void TextEdit::set_draw_minimap(bool p_draw) {
draw_minimap = p_draw;
update();
@@ -6800,16 +6658,10 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("redo"), &TextEdit::redo);
ClassDB::bind_method(D_METHOD("clear_undo_history"), &TextEdit::clear_undo_history);
- ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers);
- ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled);
ClassDB::bind_method(D_METHOD("set_draw_tabs"), &TextEdit::set_draw_tabs);
ClassDB::bind_method(D_METHOD("is_drawing_tabs"), &TextEdit::is_drawing_tabs);
ClassDB::bind_method(D_METHOD("set_draw_spaces"), &TextEdit::set_draw_spaces);
ClassDB::bind_method(D_METHOD("is_drawing_spaces"), &TextEdit::is_drawing_spaces);
- ClassDB::bind_method(D_METHOD("set_breakpoint_gutter_enabled", "enable"), &TextEdit::set_breakpoint_gutter_enabled);
- ClassDB::bind_method(D_METHOD("is_breakpoint_gutter_enabled"), &TextEdit::is_breakpoint_gutter_enabled);
- ClassDB::bind_method(D_METHOD("set_draw_fold_gutter"), &TextEdit::set_draw_fold_gutter);
- ClassDB::bind_method(D_METHOD("is_drawing_fold_gutter"), &TextEdit::is_drawing_fold_gutter);
ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled);
ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled);
@@ -6832,6 +6684,40 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_syntax_highlighter", "syntax_highlighter"), &TextEdit::set_syntax_highlighter);
ClassDB::bind_method(D_METHOD("get_syntax_highlighter"), &TextEdit::get_syntax_highlighter);
+ /* Gutters. */
+ BIND_ENUM_CONSTANT(GUTTER_TYPE_STRING);
+ BIND_ENUM_CONSTANT(GUTTER_TPYE_ICON);
+ BIND_ENUM_CONSTANT(GUTTER_TPYE_CUSTOM);
+
+ ClassDB::bind_method(D_METHOD("add_gutter", "at"), &TextEdit::add_gutter, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("remove_gutter", "gutter"), &TextEdit::remove_gutter);
+ ClassDB::bind_method(D_METHOD("get_gutter_count"), &TextEdit::get_gutter_count);
+ ClassDB::bind_method(D_METHOD("set_gutter_name", "gutter", "name"), &TextEdit::set_gutter_name);
+ ClassDB::bind_method(D_METHOD("get_gutter_name", "gutter"), &TextEdit::get_gutter_name);
+ ClassDB::bind_method(D_METHOD("set_gutter_type", "gutter", "type"), &TextEdit::set_gutter_type);
+ ClassDB::bind_method(D_METHOD("get_gutter_type", "gutter"), &TextEdit::get_gutter_type);
+ ClassDB::bind_method(D_METHOD("set_gutter_width", "gutter", "width"), &TextEdit::set_gutter_width);
+ ClassDB::bind_method(D_METHOD("get_gutter_width", "gutter"), &TextEdit::get_gutter_width);
+ ClassDB::bind_method(D_METHOD("set_gutter_draw", "gutter", "draw"), &TextEdit::set_gutter_draw);
+ ClassDB::bind_method(D_METHOD("is_gutter_drawn", "gutter"), &TextEdit::is_gutter_drawn);
+ ClassDB::bind_method(D_METHOD("set_gutter_clickable", "gutter", "clickable"), &TextEdit::set_gutter_clickable);
+ ClassDB::bind_method(D_METHOD("is_gutter_clickable", "gutter"), &TextEdit::is_gutter_clickable);
+ ClassDB::bind_method(D_METHOD("set_gutter_overwritable", "gutter", "overwritable"), &TextEdit::set_gutter_overwritable);
+ ClassDB::bind_method(D_METHOD("is_gutter_overwritable", "gutter"), &TextEdit::is_gutter_overwritable);
+ ClassDB::bind_method(D_METHOD("set_gutter_custom_draw", "column", "object", "callback"), &TextEdit::set_gutter_custom_draw);
+
+ // Line gutters.
+ ClassDB::bind_method(D_METHOD("set_line_gutter_metadata", "line", "gutter", "metadata"), &TextEdit::set_line_gutter_metadata);
+ ClassDB::bind_method(D_METHOD("get_line_gutter_metadata", "line", "gutter"), &TextEdit::get_line_gutter_metadata);
+ ClassDB::bind_method(D_METHOD("set_line_gutter_text", "line", "gutter", "text"), &TextEdit::set_line_gutter_text);
+ ClassDB::bind_method(D_METHOD("get_line_gutter_text", "line", "gutter"), &TextEdit::get_line_gutter_text);
+ ClassDB::bind_method(D_METHOD("set_line_gutter_icon", "line", "gutter", "icon"), &TextEdit::set_line_gutter_icon);
+ ClassDB::bind_method(D_METHOD("get_line_gutter_icon", "line", "gutter"), &TextEdit::get_line_gutter_icon);
+ ClassDB::bind_method(D_METHOD("set_line_gutter_item_color", "line", "gutter", "color"), &TextEdit::set_line_gutter_item_color);
+ ClassDB::bind_method(D_METHOD("get_line_gutter_item_color", "line", "gutter"), &TextEdit::get_line_gutter_item_color);
+ ClassDB::bind_method(D_METHOD("set_line_gutter_clickable", "line", "gutter", "clickable"), &TextEdit::set_line_gutter_clickable);
+ ClassDB::bind_method(D_METHOD("is_line_gutter_clickable", "line", "gutter"), &TextEdit::is_line_gutter_clickable);
+
ClassDB::bind_method(D_METHOD("set_highlight_current_line", "enabled"), &TextEdit::set_highlight_current_line);
ClassDB::bind_method(D_METHOD("is_highlight_current_line_enabled"), &TextEdit::is_highlight_current_line_enabled);
@@ -6847,9 +6733,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
- 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);
@@ -6858,11 +6741,8 @@ void TextEdit::_bind_methods() {
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");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_tabs"), "set_draw_tabs", "is_drawing_tabs");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_spaces"), "set_draw_spaces", "is_drawing_spaces");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "breakpoint_gutter"), "set_breakpoint_gutter_enabled", "is_breakpoint_gutter_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter");
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");
@@ -6890,11 +6770,12 @@ void TextEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("cursor_changed"));
ADD_SIGNAL(MethodInfo("text_changed"));
- ADD_SIGNAL(MethodInfo("line_edited_from", PropertyInfo(Variant::INT, "line")));
+ ADD_SIGNAL(MethodInfo("lines_edited_from", PropertyInfo(Variant::INT, "from_line"), PropertyInfo(Variant::INT, "to_line")));
ADD_SIGNAL(MethodInfo("request_completion"));
- ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::INT, "row")));
+ ADD_SIGNAL(MethodInfo("gutter_clicked", PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::INT, "gutter")));
+ ADD_SIGNAL(MethodInfo("gutter_added"));
+ ADD_SIGNAL(MethodInfo("gutter_removed"));
ADD_SIGNAL(MethodInfo("symbol_lookup", PropertyInfo(Variant::STRING, "symbol"), PropertyInfo(Variant::INT, "row"), PropertyInfo(Variant::INT, "column")));
- ADD_SIGNAL(MethodInfo("info_clicked", PropertyInfo(Variant::INT, "row"), PropertyInfo(Variant::STRING, "info")));
ADD_SIGNAL(MethodInfo("symbol_validate", PropertyInfo(Variant::STRING, "symbol")));
BIND_ENUM_CONSTANT(MENU_CUT);
@@ -6927,13 +6808,6 @@ TextEdit::TextEdit() {
_update_caches();
cache.row_height = 1;
cache.line_spacing = 1;
- cache.line_number_w = 1;
- cache.breakpoint_gutter_width = 0;
- breakpoint_gutter_width = 0;
- cache.fold_gutter_width = 0;
- fold_gutter_width = 0;
- info_gutter_width = 0;
- cache.info_gutter_width = 0;
set_default_cursor_shape(CURSOR_IBEAM);
indent_size = 4;
@@ -6997,15 +6871,9 @@ TextEdit::TextEdit() {
completion_active = false;
completion_line_ofs = 0;
tooltip_obj = nullptr;
- line_numbers = false;
- line_numbers_zero_padded = false;
line_length_guidelines = false;
line_length_guideline_soft_col = 80;
line_length_guideline_hard_col = 100;
- draw_bookmark_gutter = false;
- draw_breakpoint_gutter = false;
- draw_fold_gutter = false;
- draw_info_gutter = false;
hiding_enabled = false;
next_operation_is_complex = false;
scroll_past_end_of_file_enabled = false;
@@ -7043,8 +6911,6 @@ TextEdit::TextEdit() {
set_readonly(false);
menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
first_draw = true;
-
- executing_line = -1;
}
TextEdit::~TextEdit() {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index a6bc9963cc..562f4768ae 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -41,28 +41,53 @@ class TextEdit : public Control {
GDCLASS(TextEdit, Control);
public:
+ enum GutterType {
+ GUTTER_TYPE_STRING,
+ GUTTER_TPYE_ICON,
+ GUTTER_TPYE_CUSTOM
+ };
+
+private:
+ struct GutterInfo {
+ GutterType type = GutterType::GUTTER_TYPE_STRING;
+ String name = "";
+ int width = 24;
+ bool draw = true;
+ bool clickable = false;
+ bool overwritable = false;
+
+ ObjectID custom_draw_obj = ObjectID();
+ StringName custom_draw_callback;
+ };
+ Vector<GutterInfo> gutters;
+ int gutters_width = 0;
+ int gutter_padding = 0;
+
+ void _update_gutter_width();
+
class Text {
public:
+ struct Gutter {
+ Variant metadata;
+ bool clickable = false;
+
+ Ref<Texture2D> icon = Ref<Texture2D>();
+ String text = "";
+ Color color = Color(1, 1, 1);
+ };
+
struct Line {
- int width_cache : 24;
- bool marked : 1;
- bool breakpoint : 1;
- bool bookmark : 1;
- bool hidden : 1;
- bool safe : 1;
- bool has_info : 1;
- int wrap_amount_cache : 24;
- Ref<Texture2D> info_icon;
- String info;
+ Vector<Gutter> gutters;
+
+ int32_t width_cache;
+ bool marked;
+ bool hidden;
+ int32_t wrap_amount_cache;
String data;
Line() {
width_cache = 0;
marked = false;
- breakpoint = false;
- bookmark = false;
hidden = false;
- safe = false;
- has_info = false;
wrap_amount_cache = 0;
}
};
@@ -70,7 +95,8 @@ public:
private:
mutable Vector<Line> text;
Ref<Font> font;
- int indent_size;
+ int indent_size = 4;
+ int gutter_count = 0;
void _update_line_cache(int p_line) const;
@@ -79,44 +105,43 @@ public:
void set_font(const Ref<Font> &p_font);
int get_line_width(int p_line) const;
int get_max_width(bool p_exclude_hidden = false) const;
- int get_char_width(CharType c, CharType next_c, int px) const;
+ int get_char_width(char32_t c, char32_t next_c, int px) const;
void set_line_wrap_amount(int p_line, int p_wrap_amount) const;
int get_line_wrap_amount(int p_line) const;
void set(int p_line, const String &p_text);
void set_marked(int p_line, bool p_marked) { text.write[p_line].marked = p_marked; }
bool is_marked(int p_line) const { return text[p_line].marked; }
- void set_bookmark(int p_line, bool p_bookmark) { text.write[p_line].bookmark = p_bookmark; }
- bool is_bookmark(int p_line) const { return text[p_line].bookmark; }
- void set_breakpoint(int p_line, bool p_breakpoint) { text.write[p_line].breakpoint = p_breakpoint; }
- bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; }
void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; }
bool is_hidden(int p_line) const { return text[p_line].hidden; }
- void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; }
- bool is_safe(int p_line) const { return text[p_line].safe; }
- void set_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) {
- if (p_icon.is_null()) {
- text.write[p_line].has_info = false;
- return;
- }
- text.write[p_line].info_icon = p_icon;
- text.write[p_line].info = p_info;
- text.write[p_line].has_info = true;
- }
- bool has_info_icon(int p_line) const { return text[p_line].has_info; }
- const Ref<Texture2D> &get_info_icon(int p_line) const { return text[p_line].info_icon; }
- const String &get_info(int p_line) const { return text[p_line].info; }
void insert(int p_at, const String &p_text);
void remove(int p_at);
int size() const { return text.size(); }
void clear();
void clear_width_cache();
void clear_wrap_cache();
- void clear_info_icons();
_FORCE_INLINE_ const String &operator[](int p_line) const { return text[p_line].data; }
- Text() { indent_size = 4; }
+
+ /* Gutters. */
+ void add_gutter(int p_at);
+ void remove_gutter(int p_gutter);
+ void move_gutters(int p_from_line, int p_to_line);
+
+ void set_line_gutter_metadata(int p_line, int p_gutter, const Variant &p_metadata) { text.write[p_line].gutters.write[p_gutter].metadata = p_metadata; }
+ const Variant &get_line_gutter_metadata(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].metadata; }
+
+ void set_line_gutter_text(int p_line, int p_gutter, const String &p_text) { text.write[p_line].gutters.write[p_gutter].text = p_text; }
+ const String &get_line_gutter_text(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].text; }
+
+ void set_line_gutter_icon(int p_line, int p_gutter, Ref<Texture2D> p_icon) { text.write[p_line].gutters.write[p_gutter].icon = p_icon; }
+ const Ref<Texture2D> &get_line_gutter_icon(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].icon; }
+
+ void set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color) { text.write[p_line].gutters.write[p_gutter].color = p_color; }
+ const Color &get_line_gutter_item_color(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].color; }
+
+ void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable) { text.write[p_line].gutters.write[p_gutter].clickable = p_clickable; }
+ bool is_line_gutter_clickable(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].clickable; }
};
-private:
struct Cursor {
int last_fit_x;
int line, column; ///< cursor
@@ -169,60 +194,6 @@ private:
}
} selection;
- struct Cache {
- Ref<Texture2D> tab_icon;
- Ref<Texture2D> space_icon;
- Ref<Texture2D> can_fold_icon;
- Ref<Texture2D> folded_icon;
- Ref<Texture2D> folded_eol_icon;
- Ref<Texture2D> executing_icon;
- Ref<StyleBox> style_normal;
- Ref<StyleBox> style_focus;
- Ref<StyleBox> style_readonly;
- Ref<Font> font;
- Color completion_background_color;
- Color completion_selected_color;
- Color completion_existing_color;
- Color completion_font_color;
- Color caret_color;
- Color caret_background_color;
- Color line_number_color;
- Color safe_line_number_color;
- Color font_color;
- Color font_color_selected;
- Color font_color_readonly;
- Color selection_color;
- Color mark_color;
- Color bookmark_color;
- Color breakpoint_color;
- Color executing_line_color;
- Color code_folding_color;
- Color current_line_color;
- Color line_length_guideline_color;
- Color brace_mismatch_color;
- Color word_highlighted_color;
- Color search_result_color;
- Color search_result_border_color;
- Color background_color;
-
- int row_height;
- int line_spacing;
- int line_number_w;
- int breakpoint_gutter_width;
- int fold_gutter_width;
- int info_gutter_width;
- int minimap_width;
- Cache() {
- row_height = 0;
- line_spacing = 0;
- line_number_w = 0;
- breakpoint_gutter_width = 0;
- fold_gutter_width = 0;
- info_gutter_width = 0;
- minimap_width = 0;
- }
- } cache;
-
Map<int, Dictionary> syntax_highlighting_cache;
struct TextOperation {
@@ -318,19 +289,10 @@ private:
bool cursor_changed_dirty;
bool text_changed_dirty;
bool undo_enabled;
- bool line_numbers;
- bool line_numbers_zero_padded;
bool line_length_guidelines;
int line_length_guideline_soft_col;
int line_length_guideline_hard_col;
- bool draw_bookmark_gutter;
- bool draw_breakpoint_gutter;
- int breakpoint_gutter_width;
- bool draw_fold_gutter;
- int fold_gutter_width;
bool hiding_enabled;
- bool draw_info_gutter;
- int info_gutter_width;
bool draw_minimap;
int minimap_width;
Point2 minimap_char_size;
@@ -385,11 +347,8 @@ private:
bool context_menu_enabled;
bool shortcut_keys_enabled;
-
bool virtual_keyboard_enabled = true;
- int executing_line;
-
void _generate_context_menu();
int get_visible_rows() const;
@@ -447,8 +406,6 @@ private:
Size2 get_minimum_size() const override;
int _get_control_height() const;
- int get_row_height() const;
-
void _reset_caret_blink_timer();
void _toggle_draw_caret();
@@ -480,6 +437,44 @@ private:
int _calculate_spaces_till_next_right_indent(int column);
protected:
+ struct Cache {
+ Ref<Texture2D> tab_icon;
+ Ref<Texture2D> space_icon;
+ Ref<Texture2D> folded_eol_icon;
+ Ref<StyleBox> style_normal;
+ Ref<StyleBox> style_focus;
+ Ref<StyleBox> style_readonly;
+ Ref<Font> font;
+ Color completion_background_color;
+ Color completion_selected_color;
+ Color completion_existing_color;
+ Color completion_font_color;
+ Color caret_color;
+ Color caret_background_color;
+ Color font_color;
+ Color font_color_selected;
+ Color font_color_readonly;
+ Color selection_color;
+ Color mark_color;
+ Color code_folding_color;
+ Color current_line_color;
+ Color line_length_guideline_color;
+ Color brace_mismatch_color;
+ Color word_highlighted_color;
+ Color search_result_color;
+ Color search_result_border_color;
+ Color background_color;
+
+ int row_height;
+ int line_spacing;
+ int minimap_width;
+ Cache() {
+ row_height = 0;
+ line_spacing = 0;
+ minimap_width = 0;
+ }
+ } cache;
+
virtual String get_tooltip(const Point2 &p_pos) const override;
void _insert_text(int p_line, int p_char, const String &p_text, int *r_end_line = nullptr, int *r_end_char = nullptr);
@@ -488,15 +483,57 @@ protected:
void _gui_input(const Ref<InputEvent> &p_gui_input);
void _notification(int p_what);
- void _consume_pair_symbol(CharType ch);
+ void _consume_pair_symbol(char32_t ch);
void _consume_backspace_for_pair_symbol(int prev_line, int prev_column);
static void _bind_methods();
public:
+ /* Syntax Highlighting. */
Ref<SyntaxHighlighter> get_syntax_highlighter();
void set_syntax_highlighter(Ref<SyntaxHighlighter> p_syntax_highlighter);
+ /* Gutters. */
+ void add_gutter(int p_at = -1);
+ void remove_gutter(int p_gutter);
+ int get_gutter_count() const;
+
+ void set_gutter_name(int p_gutter, const String &p_name);
+ String get_gutter_name(int p_gutter) const;
+
+ void set_gutter_type(int p_gutter, GutterType p_type);
+ GutterType get_gutter_type(int p_gutter) const;
+
+ void set_gutter_width(int p_gutter, int p_width);
+ int get_gutter_width(int p_gutter) const;
+
+ void set_gutter_draw(int p_gutter, bool p_draw);
+ bool is_gutter_drawn(int p_gutter) const;
+
+ void set_gutter_clickable(int p_gutter, bool p_clickable);
+ bool is_gutter_clickable(int p_gutter) const;
+
+ void set_gutter_overwritable(int p_gutter, bool p_overwritable);
+ bool is_gutter_overwritable(int p_gutter) const;
+
+ void set_gutter_custom_draw(int p_gutter, Object *p_object, const StringName &p_callback);
+
+ // Line gutters.
+ void set_line_gutter_metadata(int p_line, int p_gutter, const Variant &p_metadata);
+ Variant get_line_gutter_metadata(int p_line, int p_gutter) const;
+
+ void set_line_gutter_text(int p_line, int p_gutter, const String &p_text);
+ String get_line_gutter_text(int p_line, int p_gutter) const;
+
+ void set_line_gutter_icon(int p_line, int p_gutter, Ref<Texture2D> p_icon);
+ Ref<Texture2D> get_line_gutter_icon(int p_line, int p_gutter) const;
+
+ void set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color);
+ Color get_line_gutter_item_color(int p_line, int p_gutter);
+
+ void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable);
+ bool is_line_gutter_clickable(int p_line, int p_gutter) const;
+
enum MenuItems {
MENU_CUT,
MENU_COPY,
@@ -534,22 +571,6 @@ public:
void insert_at(const String &p_text, int at);
int get_line_count() const;
void set_line_as_marked(int p_line, bool p_marked);
- void set_line_as_bookmark(int p_line, bool p_bookmark);
- bool is_line_set_as_bookmark(int p_line) const;
- void get_bookmarks(List<int> *p_bookmarks) const;
- Array get_bookmarks_array() const;
- void set_line_as_breakpoint(int p_line, bool p_breakpoint);
- bool is_line_set_as_breakpoint(int p_line) const;
- void set_executing_line(int p_line);
- void clear_executing_line();
- void set_line_as_safe(int p_line, bool p_safe);
- bool is_line_set_as_safe(int p_line) const;
- void get_breakpoints(List<int> *p_breakpoints) const;
- Array get_breakpoints_array() const;
- void remove_breakpoints();
-
- void set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info = "");
- void clear_info_icons();
void set_line_as_hidden(int p_line, bool p_hidden);
bool is_line_hidden(int p_line) const;
@@ -569,6 +590,7 @@ public:
String get_text();
String get_line(int line) const;
void set_line(int line, String new_text);
+ int get_row_height() const;
void backspace_at_cursor();
void indent_left();
@@ -690,39 +712,13 @@ public:
void menu_option(int p_option);
- void set_show_line_numbers(bool p_show);
- bool is_show_line_numbers_enabled() const;
-
void set_highlight_current_line(bool p_enabled);
bool is_highlight_current_line_enabled() const;
- void set_line_numbers_zero_padded(bool p_zero_padded);
-
void set_show_line_length_guidelines(bool p_show);
void set_line_length_guideline_soft_column(int p_column);
void set_line_length_guideline_hard_column(int p_column);
- void set_bookmark_gutter_enabled(bool p_draw);
- bool is_bookmark_gutter_enabled() const;
-
- void set_breakpoint_gutter_enabled(bool p_draw);
- bool is_breakpoint_gutter_enabled() const;
-
- void set_breakpoint_gutter_width(int p_gutter_width);
- int get_breakpoint_gutter_width() const;
-
- void set_draw_fold_gutter(bool p_draw);
- bool is_drawing_fold_gutter() const;
-
- void set_fold_gutter_width(int p_gutter_width);
- int get_fold_gutter_width() const;
-
- void set_draw_info_gutter(bool p_draw);
- bool is_drawing_info_gutter() const;
-
- 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;
@@ -764,6 +760,7 @@ public:
~TextEdit();
};
+VARIANT_ENUM_CAST(TextEdit::GutterType);
VARIANT_ENUM_CAST(TextEdit::MenuItems);
VARIANT_ENUM_CAST(TextEdit::SearchFlags);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 5057f84192..070948237a 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1208,8 +1208,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (drop_mode_flags && drop_mode_over == p_item) {
Rect2 r = cell_rect;
+ bool has_parent = p_item->get_children() != nullptr;
- if (drop_mode_section == -1 || drop_mode_section == 0) {
+ if (drop_mode_section == -1 || has_parent || drop_mode_section == 0) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color);
}
@@ -1218,7 +1219,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), cache.drop_position_color);
}
- if (drop_mode_section == 1 || drop_mode_section == 0) {
+ if ((drop_mode_section == 1 && !has_parent) || drop_mode_section == 0) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), cache.drop_position_color);
}
}
@@ -2403,11 +2404,16 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
cache.hover_cell = col;
if (it != old_it || col != old_col) {
- // Only need to update if mouse enters/exits a button
- bool was_over_button = old_it && old_it->cells[old_col].custom_button;
- bool is_over_button = it && it->cells[col].custom_button;
- if (was_over_button || is_over_button) {
+ if (old_it && old_col >= old_it->cells.size()) {
+ // Columns may have changed since last update().
update();
+ } else {
+ // Only need to update if mouse enters/exits a button
+ bool was_over_button = old_it && old_it->cells[old_col].custom_button;
+ bool is_over_button = it && it->cells[col].custom_button;
+ if (was_over_button || is_over_button) {
+ update();
+ }
}
}
}
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index d6d1134cc9..796408a38d 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -939,9 +939,9 @@ float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const
ERR_FAIL_COND_V(p_font.is_null(), 0);
if (p_font->has_outline()) {
- p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], Color(1, 1, 1), true);
+ p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.get_data()[0], Color(1, 1, 1), true);
}
- return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], p_modulate);
+ return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.get_data()[0], p_modulate);
}
void CanvasItem::_notify_transform(CanvasItem *p_node) {
@@ -1369,6 +1369,7 @@ void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) {
}
texture_filter = p_texture_filter;
_update_texture_filter_changed(true);
+ _change_notify();
}
CanvasItem::TextureFilter CanvasItem::get_texture_filter() const {
@@ -1421,6 +1422,7 @@ void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) {
}
texture_repeat = p_texture_repeat;
_update_texture_repeat_changed(true);
+ _change_notify();
}
CanvasItem::TextureRepeat CanvasItem::get_texture_repeat() const {
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index d9ffe770ff..3f32df87a7 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -405,10 +405,10 @@ public:
void force_update_transform();
- void set_texture_filter(TextureFilter p_texture_filter);
+ virtual void set_texture_filter(TextureFilter p_texture_filter);
TextureFilter get_texture_filter() const;
- void set_texture_repeat(TextureRepeat p_texture_repeat);
+ virtual void set_texture_repeat(TextureRepeat p_texture_repeat);
TextureRepeat get_texture_repeat() const;
// Used by control nodes to retrieve the parent's anchorable area
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 82ee4dde50..da0169b60b 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "http_request.h"
+#include "core/io/compression.h"
+#include "core/ustring.h"
void HTTPRequest::_redirect_request(const String &p_new_url) {
}
@@ -82,7 +84,51 @@ Error HTTPRequest::_parse_url(const String &p_url) {
return OK;
}
+bool HTTPRequest::has_header(const PackedStringArray &p_headers, const String &p_header_name) {
+ bool exists = false;
+
+ String lower_case_header_name = p_header_name.to_lower();
+ for (int i = 0; i < p_headers.size() && !exists; i++) {
+ String sanitized = p_headers[i].strip_edges().to_lower();
+ if (sanitized.begins_with(lower_case_header_name)) {
+ exists = true;
+ }
+ }
+
+ return exists;
+}
+
+String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const String &p_header_name) {
+ String value = "";
+
+ String lowwer_case_header_name = p_header_name.to_lower();
+ for (int i = 0; i < p_headers.size(); i++) {
+ if (p_headers[i].find(":", 0) >= 0) {
+ Vector<String> parts = p_headers[i].split(":", false, 1);
+ if (parts[0].strip_edges().to_lower() == lowwer_case_header_name) {
+ value = parts[1].strip_edges();
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
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) {
+ // Copy the string into a raw buffer
+ Vector<uint8_t> raw_data;
+
+ CharString charstr = p_request_data.utf8();
+ size_t len = charstr.length();
+ raw_data.resize(len);
+ uint8_t *w = raw_data.ptrw();
+ copymem(w, charstr.ptr(), len);
+
+ return request_raw(p_url, p_custom_headers, p_ssl_validate_domain, p_method, raw_data);
+}
+
+Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const Vector<uint8_t> &p_request_data_raw) {
ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one.");
@@ -102,7 +148,14 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h
headers = p_custom_headers;
- request_data = p_request_data;
+ if (accept_gzip) {
+ // If the user has specified a different Accept-Encoding, don't overwrite it
+ if (!has_header(headers, "Accept-Encoding")) {
+ headers.push_back("Accept-Encoding: gzip, deflate");
+ }
+ }
+
+ request_data = p_request_data_raw;
requesting = true;
@@ -288,7 +341,7 @@ bool HTTPRequest::_update_connection() {
} else {
// Did not request yet, do request
- Error err = client->request(method, request_string, headers, request_data);
+ Error err = client->request_raw(method, request_string, headers, request_data);
if (err != OK) {
call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
return true;
@@ -382,9 +435,47 @@ bool HTTPRequest::_update_connection() {
ERR_FAIL_V(false);
}
-void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
+void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data) {
cancel_request();
- emit_signal("request_completed", p_status, p_code, headers, p_data);
+
+ // Determine if the request body is compressed
+ bool is_compressed;
+ String content_encoding = get_header_value(p_headers, "Content-Encoding").to_lower();
+ Compression::Mode mode;
+ if (content_encoding == "gzip") {
+ mode = Compression::Mode::MODE_GZIP;
+ is_compressed = true;
+ } else if (content_encoding == "deflate") {
+ mode = Compression::Mode::MODE_DEFLATE;
+ is_compressed = true;
+ } else {
+ is_compressed = false;
+ }
+
+ const PackedByteArray *data = NULL;
+
+ if (accept_gzip && is_compressed && p_data.size() > 0) {
+ // Decompress request body
+ PackedByteArray *decompressed = memnew(PackedByteArray);
+ int result = Compression::decompress_dynamic(decompressed, body_size_limit, p_data.ptr(), p_data.size(), mode);
+ if (result == OK) {
+ data = decompressed;
+ } else if (result == -5) {
+ WARN_PRINT("Decompressed size of HTTP response body exceeded body_size_limit");
+ p_status = RESULT_BODY_SIZE_LIMIT_EXCEEDED;
+ // Just return the raw data if we failed to decompress it
+ data = &p_data;
+ } else {
+ WARN_PRINT("Failed to decompress HTTP response body");
+ p_status = RESULT_BODY_DECOMPRESS_FAILED;
+ // Just return the raw data if we failed to decompress it
+ data = &p_data;
+ }
+ } else {
+ data = &p_data;
+ }
+
+ emit_signal("request_completed", p_status, p_code, p_headers, *data);
}
void HTTPRequest::_notification(int p_what) {
@@ -415,6 +506,14 @@ bool HTTPRequest::is_using_threads() const {
return use_threads;
}
+void HTTPRequest::set_accept_gzip(bool p_gzip) {
+ accept_gzip = p_gzip;
+}
+
+bool HTTPRequest::is_accepting_gzip() const {
+ return accept_gzip;
+}
+
void HTTPRequest::set_body_size_limit(int p_bytes) {
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
@@ -481,6 +580,7 @@ void HTTPRequest::_timeout() {
void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("request_raw", "url", "custom_headers", "ssl_validate_domain", "method", "request_data_raw"), &HTTPRequest::request_raw, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(PackedByteArray()));
ClassDB::bind_method(D_METHOD("cancel_request"), &HTTPRequest::cancel_request);
ClassDB::bind_method(D_METHOD("get_http_client_status"), &HTTPRequest::get_http_client_status);
@@ -488,6 +588,9 @@ void HTTPRequest::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_threads", "enable"), &HTTPRequest::set_use_threads);
ClassDB::bind_method(D_METHOD("is_using_threads"), &HTTPRequest::is_using_threads);
+ ClassDB::bind_method(D_METHOD("set_accept_gzip", "enable"), &HTTPRequest::set_accept_gzip);
+ ClassDB::bind_method(D_METHOD("is_accepting_gzip"), &HTTPRequest::is_accepting_gzip);
+
ClassDB::bind_method(D_METHOD("set_body_size_limit", "bytes"), &HTTPRequest::set_body_size_limit);
ClassDB::bind_method(D_METHOD("get_body_size_limit"), &HTTPRequest::get_body_size_limit);
@@ -512,6 +615,7 @@ void HTTPRequest::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file");
ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_download_chunk_size", "get_download_chunk_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accept_gzip"), "set_accept_gzip", "is_accepting_gzip");
ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects");
ADD_PROPERTY(PropertyInfo(Variant::INT, "timeout", PROPERTY_HINT_RANGE, "0,86400"), "set_timeout", "get_timeout");
@@ -527,6 +631,7 @@ void HTTPRequest::_bind_methods() {
BIND_ENUM_CONSTANT(RESULT_SSL_HANDSHAKE_ERROR);
BIND_ENUM_CONSTANT(RESULT_NO_RESPONSE);
BIND_ENUM_CONSTANT(RESULT_BODY_SIZE_LIMIT_EXCEEDED);
+ BIND_ENUM_CONSTANT(RESULT_BODY_DECOMPRESS_FAILED);
BIND_ENUM_CONSTANT(RESULT_REQUEST_FAILED);
BIND_ENUM_CONSTANT(RESULT_DOWNLOAD_FILE_CANT_OPEN);
BIND_ENUM_CONSTANT(RESULT_DOWNLOAD_FILE_WRITE_ERROR);
@@ -544,6 +649,7 @@ HTTPRequest::HTTPRequest() {
got_response = false;
validate_ssl = false;
use_ssl = false;
+ accept_gzip = true;
response_code = 0;
request_sent = false;
requesting = false;
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
index 1409965d45..2e8931120b 100644
--- a/scene/main/http_request.h
+++ b/scene/main/http_request.h
@@ -50,6 +50,7 @@ public:
RESULT_SSL_HANDSHAKE_ERROR,
RESULT_NO_RESPONSE,
RESULT_BODY_SIZE_LIMIT_EXCEEDED,
+ RESULT_BODY_DECOMPRESS_FAILED,
RESULT_REQUEST_FAILED,
RESULT_DOWNLOAD_FILE_CANT_OPEN,
RESULT_DOWNLOAD_FILE_WRITE_ERROR,
@@ -68,12 +69,13 @@ private:
bool validate_ssl;
bool use_ssl;
HTTPClient::Method method;
- String request_data;
+ Vector<uint8_t> request_data;
bool request_sent;
Ref<HTTPClient> client;
PackedByteArray body;
volatile bool use_threads;
+ bool accept_gzip;
bool got_response;
int response_code;
@@ -102,12 +104,15 @@ private:
Error _parse_url(const String &p_url);
Error _request();
+ bool has_header(const PackedStringArray &p_headers, const String &p_header_name);
+ String get_header_value(const PackedStringArray &p_headers, const String &header_name);
+
volatile bool thread_done;
volatile bool thread_request_quit;
Thread *thread;
- void _request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
+ void _request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data);
static void _thread_func(void *p_userdata);
protected:
@@ -116,12 +121,16 @@ protected:
public:
Error request(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const String &p_request_data = ""); //connects to a full url and perform request
+ Error request_raw(const String &p_url, const Vector<String> &p_custom_headers = Vector<String>(), bool p_ssl_validate_domain = true, HTTPClient::Method p_method = HTTPClient::METHOD_GET, const Vector<uint8_t> &p_request_data_raw = Vector<uint8_t>()); //connects to a full url and perform request
void cancel_request();
HTTPClient::Status get_http_client_status() const;
void set_use_threads(bool p_use);
bool is_using_threads() const;
+ void set_accept_gzip(bool p_gzip);
+ bool is_accepting_gzip() const;
+
void set_download_file(const String &p_file);
String get_download_file() const;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 653eb698d4..e7753089c7 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1094,7 +1094,7 @@ String increase_numeric_string(const String &s) {
if (!carry) {
break;
}
- CharType n = s[i];
+ char32_t n = s[i];
if (n == '9') { // keep carry as true: 9 + 1
res[i] = '0';
} else {
@@ -1155,7 +1155,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co
String name_string = name;
String nums;
for (int i = name_string.length() - 1; i >= 0; i--) {
- CharType n = name_string[i];
+ char32_t n = name_string[i];
if (n >= '0' && n <= '9') {
nums = String::chr(name_string[i]) + nums;
} else {
@@ -1327,6 +1327,9 @@ int Node::get_child_count() const {
}
Node *Node::get_child(int p_index) const {
+ if (p_index < 0) {
+ p_index += data.children.size();
+ }
ERR_FAIL_INDEX_V(p_index, data.children.size(), nullptr);
return data.children[p_index];
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 0f74f2e973..e5ab4f9958 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCENE_MAIN_LOOP_H
-#define SCENE_MAIN_LOOP_H
+#ifndef SCENE_TREE_H
+#define SCENE_TREE_H
#include "core/io/multiplayer_api.h"
#include "core/os/main_loop.h"
@@ -354,4 +354,4 @@ public:
VARIANT_ENUM_CAST(SceneTree::GroupCallFlags);
-#endif
+#endif // SCENE_TREE_H
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index d962171555..b29b40ea5f 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1509,7 +1509,7 @@ void Viewport::_gui_show_tooltip() {
}
Control *which = nullptr;
- String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.tooltip_pos), &which);
+ String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.last_mouse_pos), &which);
tooltip = tooltip.strip_edges();
if (tooltip.length() == 0) {
return; // bye
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 68ffdfe2e8..7c2350d1c0 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -246,7 +246,10 @@ void Window::_make_window() {
}
}
+ _update_window_callbacks();
+
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
+ DisplayServer::get_singleton()->show_window(window_id);
}
void Window::_update_from_window() {
@@ -378,7 +381,6 @@ void Window::set_visible(bool p_visible) {
}
if (p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) {
_make_window();
- _update_window_callbacks();
}
} else {
if (visible) {
@@ -737,7 +739,6 @@ void Window::_notification(int p_what) {
//create
if (visible) {
_make_window();
- _update_window_callbacks();
}
}
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 0f6475cf0d..820513c53d 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -81,6 +81,7 @@
#include "scene/gui/center_container.h"
#include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
+#include "scene/gui/code_edit.h"
#include "scene/gui/color_picker.h"
#include "scene/gui/color_rect.h"
#include "scene/gui/control.h"
@@ -230,6 +231,7 @@ static Ref<ResourceFormatLoaderDynamicFont> resource_loader_dynamic_font;
static Ref<ResourceFormatLoaderStreamTexture2D> resource_loader_stream_texture;
static Ref<ResourceFormatLoaderStreamTextureLayered> resource_loader_texture_layered;
+static Ref<ResourceFormatLoaderStreamTexture3D> resource_loader_texture_3d;
static Ref<ResourceFormatLoaderBMFont> resource_loader_bmfont;
@@ -252,6 +254,9 @@ void register_scene_types() {
resource_loader_texture_layered.instance();
ResourceLoader::add_resource_format_loader(resource_loader_texture_layered);
+ resource_loader_texture_3d.instance();
+ ResourceLoader::add_resource_format_loader(resource_loader_texture_3d);
+
resource_saver_text.instance();
ResourceSaver::add_resource_format_saver(resource_saver_text, true);
@@ -291,7 +296,7 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<ShortCut>();
+ ClassDB::register_class<Shortcut>();
ClassDB::register_class<Control>();
ClassDB::register_class<Button>();
ClassDB::register_class<Label>();
@@ -347,6 +352,7 @@ void register_scene_types() {
ClassDB::register_class<Tree>();
ClassDB::register_class<TextEdit>();
+ ClassDB::register_class<CodeEdit>();
ClassDB::register_class<SyntaxHighlighter>();
ClassDB::register_class<CodeHighlighter>();
@@ -549,6 +555,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTexture>();
ClassDB::register_virtual_class<VisualShaderNodeSample3D>();
ClassDB::register_class<VisualShaderNodeTexture2DArray>();
+ ClassDB::register_class<VisualShaderNodeTexture3D>();
ClassDB::register_class<VisualShaderNodeCubemap>();
ClassDB::register_virtual_class<VisualShaderNodeUniform>();
ClassDB::register_class<VisualShaderNodeUniformRef>();
@@ -561,6 +568,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTextureUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>();
ClassDB::register_class<VisualShaderNodeTexture2DArrayUniform>();
+ ClassDB::register_class<VisualShaderNodeTexture3DUniform>();
ClassDB::register_class<VisualShaderNodeCubemapUniform>();
ClassDB::register_class<VisualShaderNodeIf>();
ClassDB::register_class<VisualShaderNodeSwitch>();
@@ -701,6 +709,9 @@ void register_scene_types() {
ClassDB::register_class<CameraTexture>();
ClassDB::register_virtual_class<TextureLayered>();
ClassDB::register_virtual_class<ImageTextureLayered>();
+ ClassDB::register_virtual_class<Texture3D>();
+ ClassDB::register_class<ImageTexture3D>();
+ ClassDB::register_class<StreamTexture3D>();
ClassDB::register_class<Cubemap>();
ClassDB::register_class<CubemapArray>();
ClassDB::register_class<Texture2DArray>();
@@ -864,6 +875,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("RemoteTransform", "RemoteTransform3D");
ClassDB::add_compatibility_class("RigidBody", "RigidBody3D");
ClassDB::add_compatibility_class("Shape", "Shape3D");
+ ClassDB::add_compatibility_class("ShortCut", "Shortcut");
ClassDB::add_compatibility_class("Skeleton", "Skeleton3D");
ClassDB::add_compatibility_class("SkeletonIK", "SkeletonIK3D");
ClassDB::add_compatibility_class("SliderJoint", "SliderJoint3D");
@@ -946,6 +958,9 @@ void unregister_scene_types() {
ResourceLoader::remove_resource_format_loader(resource_loader_texture_layered);
resource_loader_texture_layered.unref();
+ ResourceLoader::remove_resource_format_loader(resource_loader_texture_3d);
+ resource_loader_texture_3d.unref();
+
ResourceLoader::remove_resource_format_loader(resource_loader_stream_texture);
resource_loader_stream_texture.unref();
diff --git a/scene/resources/default_theme/bookmark.png b/scene/resources/default_theme/bookmark.png
new file mode 100644
index 0000000000..9718cf53b6
--- /dev/null
+++ b/scene/resources/default_theme/bookmark.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 9008f6d5b9..f65f78b332 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -382,8 +382,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("tab", "TextEdit", make_icon(tab_png));
theme->set_icon("space", "TextEdit", make_icon(space_png));
- theme->set_icon("folded", "TextEdit", make_icon(arrow_right_png));
- theme->set_icon("fold", "TextEdit", make_icon(arrow_down_png));
theme->set_font("font", "TextEdit", Ref<Font>());
@@ -398,16 +396,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
theme->set_color("selection_color", "TextEdit", font_color_selection);
theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4));
- theme->set_color("bookmark_color", "TextEdit", Color(0.08, 0.49, 0.98));
- theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2));
- theme->set_color("executing_line_color", "TextEdit", Color(0.2, 0.8, 0.2, 0.4));
theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "TextEdit", control_font_color);
theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0));
theme->set_color("brace_mismatch_color", "TextEdit", Color(1, 0.2, 0.2));
- theme->set_color("line_number_color", "TextEdit", Color(0.67, 0.67, 0.67, 0.4));
- theme->set_color("safe_line_number_color", "TextEdit", Color(0.67, 0.78, 0.67, 0.6));
theme->set_color("word_highlighted_color", "TextEdit", Color(0.8, 0.9, 0.9, 0.15));
theme->set_constant("completion_lines", "TextEdit", 7);
@@ -415,6 +408,50 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("completion_scroll_width", "TextEdit", 3);
theme->set_constant("line_spacing", "TextEdit", 4 * scale);
+ // CodeEdit
+ theme->set_stylebox("normal", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
+ theme->set_stylebox("focus", "CodeEdit", focus);
+ theme->set_stylebox("read_only", "CodeEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0));
+ theme->set_stylebox("completion", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
+
+ theme->set_icon("tab", "CodeEdit", make_icon(tab_png));
+ theme->set_icon("space", "CodeEdit", make_icon(space_png));
+ theme->set_icon("breakpoint", "CodeEdit", make_icon(graph_port_png));
+ theme->set_icon("bookmark", "CodeEdit", make_icon(bookmark_png));
+ theme->set_icon("executing_line", "CodeEdit", make_icon(arrow_right_png));
+ theme->set_icon("can_fold", "CodeEdit", make_icon(arrow_down_png));
+ theme->set_icon("folded", "CodeEdit", make_icon(arrow_right_png));
+
+ theme->set_font("font", "CodeEdit", Ref<Font>());
+
+ theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0));
+ theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2));
+ theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27));
+ theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13));
+ theme->set_color("completion_scroll_color", "CodeEdit", control_font_color_pressed);
+ theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67));
+ theme->set_color("font_color", "CodeEdit", control_font_color);
+ theme->set_color("font_color_selected", "CodeEdit", Color(0, 0, 0));
+ theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("selection_color", "CodeEdit", font_color_selection);
+ theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4));
+ theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
+ theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3));
+ theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
+ theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
+ theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
+ theme->set_color("caret_color", "CodeEdit", control_font_color);
+ theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0));
+ theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2));
+ theme->set_color("line_number_color", "CodeEdit", Color(0.67, 0.67, 0.67, 0.4));
+ theme->set_color("safe_line_number_color", "CodeEdit", Color(0.67, 0.78, 0.67, 0.6));
+ theme->set_color("word_highlighted_color", "CodeEdit", Color(0.8, 0.9, 0.9, 0.15));
+
+ theme->set_constant("completion_lines", "CodeEdit", 7);
+ theme->set_constant("completion_max_width", "CodeEdit", 50);
+ theme->set_constant("completion_scroll_width", "CodeEdit", 3);
+ theme->set_constant("line_spacing", "CodeEdit", 4 * scale);
+
Ref<Texture2D> empty_icon = memnew(ImageTexture);
// HScrollBar
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index edcdb90db9..a15efb593a 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -10,6 +10,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char bookmark_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char button_disabled_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 99f87dd6ed..bc983c1d7e 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -239,7 +239,7 @@ float DynamicFontAtSize::get_underline_thickness() const {
return underline_thickness;
}
-const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
+const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
const Character *chr = char_map.getptr(p_char);
ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr)));
@@ -271,7 +271,7 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon
return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this));
}
-Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
+Size2 DynamicFontAtSize::get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
if (!valid) {
return Size2(1, 1);
}
@@ -297,7 +297,7 @@ String DynamicFontAtSize::get_available_chars() const {
FT_ULong charcode = FT_Get_First_Char(face, &gindex);
while (gindex != 0) {
if (charcode != 0) {
- chars += CharType(charcode);
+ chars += char32_t(charcode);
}
charcode = FT_Get_Next_Char(face, charcode, &gindex);
}
@@ -305,7 +305,7 @@ String DynamicFontAtSize::get_available_chars() const {
return chars;
}
-float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const {
+float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const {
if (!valid) {
return 0;
}
@@ -560,7 +560,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
return chr;
}
-DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) {
+DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(char32_t p_char) {
Character ret = Character::not_found();
if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) {
@@ -596,7 +596,7 @@ cleanup_stroker:
return ret;
}
-void DynamicFontAtSize::_update_char(CharType p_char) {
+void DynamicFontAtSize::_update_char(char32_t p_char) {
if (char_map.has(p_char)) {
return;
}
@@ -849,7 +849,7 @@ float DynamicFont::get_underline_thickness() const {
return data_at_size->get_underline_thickness();
}
-Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const {
+Size2 DynamicFont::get_char_size(char32_t p_char, char32_t p_next) const {
if (!data_at_size.is_valid()) {
return Size2(1, 1);
}
@@ -891,7 +891,7 @@ bool DynamicFont::has_outline() const {
return outline_cache_id.outline_size > 0;
}
-float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
+float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const {
const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size;
if (!font_at_size.is_valid()) {
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index e8637e7e34..a881e21da8 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -159,17 +159,17 @@ class DynamicFontAtSize : public Reference {
int y;
};
- const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
- Character _make_outline_char(CharType p_char);
+ const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
+ Character _make_outline_char(char32_t p_char);
TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
static unsigned long _ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count);
static void _ft_stream_close(FT_Stream stream);
- HashMap<CharType, Character> char_map;
+ HashMap<char32_t, Character> char_map;
- _FORCE_INLINE_ void _update_char(CharType p_char);
+ _FORCE_INLINE_ void _update_char(char32_t p_char);
friend class DynamicFontData;
Ref<DynamicFontData> font;
@@ -188,10 +188,10 @@ public:
float get_underline_position() const;
float get_underline_thickness() const;
- Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
+ Size2 get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
String get_available_chars() const;
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const;
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const;
void set_texture_flags(uint32_t p_flags);
void update_oversampling();
@@ -277,14 +277,14 @@ public:
virtual float get_underline_position() const override;
virtual float get_underline_thickness() const override;
- virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const override;
+ virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override;
String get_available_chars() const;
virtual bool is_distance_field_hint() const override;
virtual bool has_outline() const override;
- virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
+ virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
SelfList<DynamicFont> font_list;
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index ccab88a153..7cc39f661d 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -125,7 +125,7 @@ void BitmapFont::_set_chars(const Vector<int> &p_chars) {
Vector<int> BitmapFont::_get_chars() const {
Vector<int> chars;
- const CharType *key = nullptr;
+ const char32_t *key = nullptr;
while ((key = char_map.next(key))) {
const Character *c = char_map.getptr(*key);
@@ -272,7 +272,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
}
}
} else if (type == "char") {
- CharType idx = 0;
+ char32_t idx = 0;
if (keys.has("id")) {
idx = keys["id"].to_int();
}
@@ -313,7 +313,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
add_char(idx, texture, rect, ofs, advance);
} else if (type == "kerning") {
- CharType first = 0, second = 0;
+ char32_t first = 0, second = 0;
int k = 0;
if (keys.has("first")) {
@@ -385,10 +385,10 @@ int BitmapFont::get_character_count() const {
return char_map.size();
};
-Vector<CharType> BitmapFont::get_char_keys() const {
- Vector<CharType> chars;
+Vector<char32_t> BitmapFont::get_char_keys() const {
+ Vector<char32_t> chars;
chars.resize(char_map.size());
- const CharType *ct = nullptr;
+ const char32_t *ct = nullptr;
int count = 0;
while ((ct = char_map.next(ct))) {
chars.write[count++] = *ct;
@@ -397,7 +397,7 @@ Vector<CharType> BitmapFont::get_char_keys() const {
return chars;
};
-BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
+BitmapFont::Character BitmapFont::get_character(char32_t p_char) const {
if (!char_map.has(p_char)) {
ERR_FAIL_V(Character());
};
@@ -405,7 +405,7 @@ BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
return char_map[p_char];
};
-void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+void BitmapFont::add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
if (p_advance < 0) {
p_advance = p_rect.size.width;
}
@@ -420,7 +420,7 @@ void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rec
char_map[p_char] = c;
}
-void BitmapFont::add_kerning_pair(CharType p_A, CharType p_B, int p_kerning) {
+void BitmapFont::add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) {
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
@@ -444,7 +444,7 @@ Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
return ret;
}
-int BitmapFont::get_kerning_pair(CharType p_A, CharType p_B) const {
+int BitmapFont::get_kerning_pair(char32_t p_A, char32_t p_B) const {
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
@@ -482,7 +482,7 @@ Size2 Font::get_string_size(const String &p_string) const {
if (l == 0) {
return Size2(0, get_height());
}
- const CharType *sptr = &p_string[0];
+ const char32_t *sptr = &p_string[0];
for (int i = 0; i < l; i++) {
w += get_char_size(sptr[i], sptr[i + 1]).width;
@@ -534,7 +534,7 @@ Ref<BitmapFont> BitmapFont::get_fallback() const {
return fallback;
}
-float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
+float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const {
const Character *c = char_map.getptr(p_char);
if (!c) {
@@ -556,7 +556,7 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c
return get_char_size(p_char, p_next).width;
}
-Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const {
+Size2 BitmapFont::get_char_size(char32_t p_char, char32_t p_next) const {
const Character *c = char_map.getptr(p_char);
if (!c) {
diff --git a/scene/resources/font.h b/scene/resources/font.h
index e6b296800b..c739520da3 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -49,7 +49,7 @@ public:
virtual float get_underline_position() const = 0;
virtual float get_underline_thickness() const = 0;
- virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0;
+ virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const = 0;
Size2 get_string_size(const String &p_string) const;
Size2 get_wordwrap_string_size(const String &p_string, float p_width) const;
@@ -59,7 +59,7 @@ public:
void draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate = Color(1, 1, 1), const Color &p_outline_modulate = Color(1, 1, 1)) const;
virtual bool has_outline() const { return false; }
- virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0;
+ virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0;
void update_changes();
Font();
@@ -74,8 +74,8 @@ class FontDrawer {
struct PendingDraw {
RID canvas_item;
Point2 pos;
- CharType chr;
- CharType next;
+ char32_t chr;
+ char32_t next;
Color modulate;
};
@@ -88,7 +88,7 @@ public:
has_outline = p_font->has_outline();
}
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1)) {
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1)) {
if (has_outline) {
PendingDraw draw = { p_canvas_item, p_pos, p_char, p_next, p_modulate };
pending_draws.push_back(draw);
@@ -137,7 +137,7 @@ public:
};
private:
- HashMap<CharType, Character> char_map;
+ HashMap<char32_t, Character> char_map;
Map<KerningPairKey, int> kerning_map;
float height;
@@ -169,20 +169,20 @@ public:
float get_underline_thickness() const override;
void add_texture(const Ref<Texture2D> &p_texture);
- void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
+ void add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
int get_character_count() const;
- Vector<CharType> get_char_keys() const;
- Character get_character(CharType p_char) const;
+ Vector<char32_t> get_char_keys() const;
+ Character get_character(char32_t p_char) const;
int get_texture_count() const;
Ref<Texture2D> get_texture(int p_idx) const;
- void add_kerning_pair(CharType p_A, CharType p_B, int p_kerning);
- int get_kerning_pair(CharType p_A, CharType p_B) const;
+ void add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning);
+ int get_kerning_pair(char32_t p_A, char32_t p_B) const;
Vector<KerningPairKey> get_kerning_pair_keys() const;
- Size2 get_char_size(CharType p_char, CharType p_next = 0) const override;
+ Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override;
void set_fallback(const Ref<BitmapFont> &p_fallback);
Ref<BitmapFont> get_fallback() const;
@@ -192,7 +192,7 @@ public:
void set_distance_field_hint(bool p_distance_field);
bool is_distance_field_hint() const override;
- float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
+ float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override;
BitmapFont();
~BitmapFont();
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index 4bcc52776b..b720653f91 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -129,7 +129,7 @@ void Gradient::add_point(float p_offset, const Color &p_color) {
void Gradient::remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, points.size());
- ERR_FAIL_COND(points.size() <= 2);
+ ERR_FAIL_COND(points.size() <= 1);
points.remove(p_index);
emit_signal(CoreStringNames::get_singleton()->changed);
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index fd1fa1b48f..b0a30a5627 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -209,7 +209,6 @@ public:
void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data);
int get_surface_count() const override;
- void surface_remove(int p_idx);
void clear_surfaces();
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 7b78398669..450e2c16e3 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GRID_THEME_H
-#define GRID_THEME_H
+#ifndef MESH_LIBRARY_H
+#define MESH_LIBRARY_H
#include "core/map.h"
#include "core/resource.h"
@@ -96,4 +96,4 @@ public:
~MeshLibrary();
};
-#endif // CUBE_GRID_THEME_H
+#endif // MESH_LIBRARY_H
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index cb201bc539..5e8bfd9387 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -848,7 +848,7 @@ Error SceneState::pack(Node *p_scene) {
Map<Node *, int> node_map;
Map<Node *, int> nodepath_map;
- //if using scene inheritance, pack the scene it inherits from
+ // If using scene inheritance, pack the scene it inherits from.
if (scene->get_scene_inherited_state().is_valid()) {
String path = scene->get_scene_inherited_state()->get_path();
Ref<PackedScene> instance = ResourceLoader::load(path);
@@ -856,8 +856,8 @@ Error SceneState::pack(Node *p_scene) {
base_scene_idx = _vm_get_variant(instance, variant_map);
}
}
- //instanced, only direct sub-scnes are supported of course
+ // Instanced, only direct sub-scenes are supported of course.
Error err = _parse_node(scene, scene, -1, name_map, variant_map, node_map, nodepath_map);
if (err) {
clear();
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index fc92a721db..4bbfa8965a 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -91,13 +91,13 @@ void ParticlesMaterial::init_shaders() {
shader_names->emission_texture_normal = "emission_texture_normal";
shader_names->emission_texture_color = "emission_texture_color";
- shader_names->trail_divisor = "trail_divisor";
- shader_names->trail_size_modifier = "trail_size_modifier";
- shader_names->trail_color_modifier = "trail_color_modifier";
-
shader_names->gravity = "gravity";
shader_names->lifetime_randomness = "lifetime_randomness";
+
+ shader_names->sub_emitter_frequency = "sub_emitter_frequency";
+ shader_names->sub_emitter_amount_at_end = "sub_emitter_amount_at_end";
+ shader_names->sub_emitter_keep_velocity = "sub_emitter_keep_velocity";
}
void ParticlesMaterial::finish_shaders() {
@@ -192,9 +192,17 @@ void ParticlesMaterial::_update_shader() {
}
}
- code += "uniform vec4 color_value : hint_color;\n";
+ if (sub_emitter_mode != SUB_EMITTER_DISABLED) {
+ if (sub_emitter_mode == SUB_EMITTER_CONSTANT) {
+ code += "uniform float sub_emitter_frequency;\n";
+ }
+ if (sub_emitter_mode == SUB_EMITTER_AT_END) {
+ code += "uniform int sub_emitter_amount_at_end;\n";
+ }
+ code += "uniform bool sub_emitter_keep_velocity;\n";
+ }
- code += "uniform int trail_divisor;\n";
+ code += "uniform vec4 color_value : hint_color;\n";
code += "uniform vec3 gravity;\n";
@@ -239,14 +247,6 @@ void ParticlesMaterial::_update_shader() {
code += "uniform sampler2D anim_offset_texture;\n";
}
- if (trail_size_modifier.is_valid()) {
- code += "uniform sampler2D trail_size_modifier;\n";
- }
-
- if (trail_color_modifier.is_valid()) {
- code += "uniform sampler2D trail_color_modifier;\n";
- }
-
//need a random function
code += "\n\n";
code += "float rand_from_seed(inout uint seed) {\n";
@@ -277,8 +277,8 @@ void ParticlesMaterial::_update_shader() {
code += "}\n";
code += "\n";
- code += "void vertex() {\n";
- code += " uint base_number = NUMBER / uint(trail_divisor);\n";
+ code += "void compute() {\n";
+ code += " uint base_number = NUMBER;\n";
code += " uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n";
code += " float angle_rand = rand_from_seed(alt_seed);\n";
code += " float scale_rand = rand_from_seed(alt_seed);\n";
@@ -293,17 +293,7 @@ void ParticlesMaterial::_update_shader() {
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
}
- code += " 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";
- } else {
- code += " float tex_linear_velocity = 0.0;\n";
- }
+ code += " if (RESTART) {\n";
if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(0.0, 0.0), 0.0).r;\n";
@@ -319,25 +309,34 @@ void ParticlesMaterial::_update_shader() {
code += " float spread_rad = spread * degree_to_rad;\n";
+ code += " if (RESTART_VELOCITY) {\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";
+ } else {
+ code += " float tex_linear_velocity = 0.0;\n";
+ }
+
if (flags[FLAG_DISABLE_Z]) {
- code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
- code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
- code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
- code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
+ code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
+ code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
} else {
//initiate velocity spread in 3D
- code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
- code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
- code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n";
- code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n";
- code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
- code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
- code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
- code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
- code += " vec_direction = normalize(vec_direction);\n";
- code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
+ code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n";
+ code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n";
+ code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n";
+ code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n";
+ code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n";
+ code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n";
+ code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
+ code += " vec_direction = normalize(vec_direction);\n";
+ code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
}
+ code += " }\n";
code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
@@ -345,35 +344,38 @@ void ParticlesMaterial::_update_shader() {
code += " CUSTOM.w = (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)
+ code += " if (RESTART_POSITION) {\n";
+
switch (emission_shape) {
case EMISSION_SHAPE_POINT: {
- //do none
+ //do none, identity (will later be multiplied by emission transform)
+ code += " TRANSFORM = mat4(vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n";
} break;
case EMISSION_SHAPE_SPHERE: {
- code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n";
- code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n";
- code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n";
- code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n";
+ code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n";
+ code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n";
+ code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n";
+ code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n";
} break;
case EMISSION_SHAPE_BOX: {
- code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n";
+ code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n";
} break;
case EMISSION_SHAPE_POINTS:
case EMISSION_SHAPE_DIRECTED_POINTS: {
- code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n";
+ code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n";
if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
if (flags[FLAG_DISABLE_Z]) {
- code += " mat2 rotm;";
- code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n";
- code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n";
- code += " VELOCITY.xy = rotm * VELOCITY.xy;\n";
+ code += " mat2 rotm;";
+ code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n";
+ code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n";
+ code += " if (RESTART_VELOCITY) VELOCITY.xy = rotm * VELOCITY.xy;\n";
} else {
- code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n";
- code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n";
- code += " vec3 tangent = normalize(cross(v0, normal));\n";
- code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
- code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n";
+ code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n";
+ code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n";
+ code += " vec3 tangent = normalize(cross(v0, normal));\n";
+ code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
+ code += " if (RESTART_VELOCITY) VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n";
}
}
} break;
@@ -381,12 +383,14 @@ void ParticlesMaterial::_update_shader() {
break;
}
}
- code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
- code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
+
+ code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
+ code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " VELOCITY.z = 0.0;\n";
- code += " TRANSFORM[3].z = 0.0;\n";
+ code += " VELOCITY.z = 0.0;\n";
+ code += " TRANSFORM[3].z = 0.0;\n";
}
+ code += " }\n";
code += " } else {\n";
@@ -540,11 +544,6 @@ void ParticlesMaterial::_update_shader() {
if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) {
code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n";
}
- if (trail_color_modifier.is_valid()) {
- code += " if (trail_divisor > 1) {\n";
- code += " COLOR *= textureLod(trail_color_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0);\n";
- code += " }\n";
- }
code += "\n";
if (flags[FLAG_DISABLE_Z]) {
@@ -592,11 +591,6 @@ void ParticlesMaterial::_update_shader() {
code += " if (base_scale < 0.000001) {\n";
code += " base_scale = 0.000001;\n";
code += " }\n";
- if (trail_size_modifier.is_valid()) {
- code += " if (trail_divisor > 1) {\n";
- code += " base_scale *= textureLod(trail_size_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0).r;\n";
- code += " }\n";
- }
code += " TRANSFORM[0].xyz *= base_scale;\n";
code += " TRANSFORM[1].xyz *= base_scale;\n";
@@ -605,6 +599,33 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY.z = 0.0;\n";
code += " TRANSFORM[3].z = 0.0;\n";
}
+ if (sub_emitter_mode != SUB_EMITTER_DISABLED) {
+ code += " int emit_count = 0;\n";
+ switch (sub_emitter_mode) {
+ case SUB_EMITTER_CONSTANT: {
+ code += " float interval_from = CUSTOM.y * LIFETIME - DELTA;\n";
+ code += " float interval_rem = sub_emitter_frequency - mod(interval_from,sub_emitter_frequency);\n";
+ code += " if (DELTA >= interval_rem) emit_count = 1;\n";
+ } break;
+ case SUB_EMITTER_AT_COLLISION: {
+ //not implemented yet
+ } break;
+ case SUB_EMITTER_AT_END: {
+ //not implemented yet
+ code += " float unit_delta = DELTA/LIFETIME;\n";
+ code += " float end_time = CUSTOM.w * 0.95;\n"; // if we do at the end we might miss it, as it can just get deactivated by emitter
+ code += " if (CUSTOM.y < end_time && (CUSTOM.y + unit_delta) >= end_time) emit_count = sub_emitter_amount_at_end;\n";
+ } break;
+ default: {
+ }
+ }
+ code += " for(int i=0;i<emit_count;i++) {\n";
+ code += " uint flags = FLAG_EMIT_POSITION|FLAG_EMIT_ROT_SCALE;\n";
+ code += " if (sub_emitter_keep_velocity) flags|=FLAG_EMIT_VELOCITY;\n";
+ code += " emit_particle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n";
+ code += " }";
+ }
+
code += " if (CUSTOM.y > CUSTOM.w) {";
code += " ACTIVE = false;\n";
code += " }\n";
@@ -951,41 +972,6 @@ int ParticlesMaterial::get_emission_point_count() const {
return emission_point_count;
}
-void ParticlesMaterial::set_trail_divisor(int p_divisor) {
- trail_divisor = p_divisor;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor);
-}
-
-int ParticlesMaterial::get_trail_divisor() const {
- return trail_divisor;
-}
-
-void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) {
- trail_size_modifier = p_trail_size_modifier;
-
- Ref<CurveTexture> curve = trail_size_modifier;
- if (curve.is_valid()) {
- curve->ensure_default_setup();
- }
-
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_size_modifier, curve);
- _queue_shader_change();
-}
-
-Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const {
- return trail_size_modifier;
-}
-
-void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) {
- trail_color_modifier = p_trail_color_modifier;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, p_trail_color_modifier);
- _queue_shader_change();
-}
-
-Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const {
- return trail_color_modifier;
-}
-
void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) {
gravity = p_gravity;
Vector3 gset = gravity;
@@ -1038,11 +1024,54 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
+ if (property.name == "sub_emitter_frequency" && sub_emitter_mode != SUB_EMITTER_CONSTANT) {
+ property.usage = 0;
+ }
+
+ if (property.name == "sub_emitter_amount_at_end" && sub_emitter_mode != SUB_EMITTER_AT_END) {
+ property.usage = 0;
+ }
+
if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) {
property.usage = 0;
}
}
+void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) {
+ sub_emitter_mode = p_sub_emitter_mode;
+ _queue_shader_change();
+ _change_notify();
+}
+
+ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const {
+ return sub_emitter_mode;
+}
+
+void ParticlesMaterial::set_sub_emitter_frequency(float p_frequency) {
+ sub_emitter_frequency = p_frequency;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pas delta instead of frequency, since its easier to compute
+}
+float ParticlesMaterial::get_sub_emitter_frequency() const {
+ return sub_emitter_frequency;
+}
+
+void ParticlesMaterial::set_sub_emitter_amount_at_end(int p_amount) {
+ sub_emitter_amount_at_end = p_amount;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_amount_at_end, p_amount);
+}
+
+int ParticlesMaterial::get_sub_emitter_amount_at_end() const {
+ return sub_emitter_amount_at_end;
+}
+
+void ParticlesMaterial::set_sub_emitter_keep_velocity(bool p_enable) {
+ sub_emitter_keep_velocity = p_enable;
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_keep_velocity, p_enable);
+}
+bool ParticlesMaterial::get_sub_emitter_keep_velocity() const {
+ return sub_emitter_keep_velocity;
+}
+
Shader::Mode ParticlesMaterial::get_shader_mode() const {
return Shader::MODE_PARTICLES;
}
@@ -1096,27 +1125,27 @@ void ParticlesMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count);
ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count);
- ClassDB::bind_method(D_METHOD("set_trail_divisor", "divisor"), &ParticlesMaterial::set_trail_divisor);
- ClassDB::bind_method(D_METHOD("get_trail_divisor"), &ParticlesMaterial::get_trail_divisor);
-
- ClassDB::bind_method(D_METHOD("set_trail_size_modifier", "texture"), &ParticlesMaterial::set_trail_size_modifier);
- ClassDB::bind_method(D_METHOD("get_trail_size_modifier"), &ParticlesMaterial::get_trail_size_modifier);
-
- ClassDB::bind_method(D_METHOD("set_trail_color_modifier", "texture"), &ParticlesMaterial::set_trail_color_modifier);
- ClassDB::bind_method(D_METHOD("get_trail_color_modifier"), &ParticlesMaterial::get_trail_color_modifier);
-
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);
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_mode"), &ParticlesMaterial::get_sub_emitter_mode);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_mode", "mode"), &ParticlesMaterial::set_sub_emitter_mode);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_frequency"), &ParticlesMaterial::get_sub_emitter_frequency);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_frequency", "hz"), &ParticlesMaterial::set_sub_emitter_frequency);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_end"), &ParticlesMaterial::get_sub_emitter_amount_at_end);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_end", "amount"), &ParticlesMaterial::set_sub_emitter_amount_at_end);
+
+ ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticlesMaterial::get_sub_emitter_keep_velocity);
+ ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticlesMaterial::set_sub_emitter_keep_velocity);
+
ADD_GROUP("Time", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "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");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier");
+
ADD_GROUP("Emission Shape", "emission_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius");
@@ -1186,6 +1215,12 @@ void ParticlesMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET);
+ ADD_GROUP("Sub Emitter", "sub_emitter_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,AtEnd,AtCollision"), "set_sub_emitter_mode", "get_sub_emitter_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_sub_emitter_frequency", "get_sub_emitter_frequency");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity");
+
BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_ORBIT_VELOCITY);
@@ -1211,6 +1246,12 @@ void ParticlesMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
+
+ BIND_ENUM_CONSTANT(SUB_EMITTER_DISABLED);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_AT_COLLISION);
+ BIND_ENUM_CONSTANT(SUB_EMITTER_MAX);
}
ParticlesMaterial::ParticlesMaterial() :
@@ -1233,11 +1274,15 @@ ParticlesMaterial::ParticlesMaterial() :
set_emission_shape(EMISSION_SHAPE_POINT);
set_emission_sphere_radius(1);
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;
+ set_sub_emitter_mode(SUB_EMITTER_DISABLED);
+ set_sub_emitter_frequency(4);
+ set_sub_emitter_amount_at_end(1);
+ set_sub_emitter_keep_velocity(false);
+
for (int i = 0; i < PARAM_MAX; i++) {
set_param_randomness(Parameter(i), 0);
}
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index 1c1b6c92f9..fa8858f67f 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -34,12 +34,22 @@
#ifndef PARTICLES_MATERIAL_H
#define PARTICLES_MATERIAL_H
+/*
+ TODO:
+-Path following
+*Manual emission
+-Sub Emitters
+-Attractors
+-Emitter positions deformable by bones
+-Collision
+-Proper trails
+*/
+
class ParticlesMaterial : public Material {
GDCLASS(ParticlesMaterial, Material);
public:
enum Parameter {
-
PARAM_INITIAL_LINEAR_VELOCITY,
PARAM_ANGULAR_VELOCITY,
PARAM_ORBIT_VELOCITY,
@@ -71,6 +81,14 @@ public:
EMISSION_SHAPE_MAX
};
+ enum SubEmitterMode {
+ SUB_EMITTER_DISABLED,
+ SUB_EMITTER_CONSTANT,
+ SUB_EMITTER_AT_END,
+ SUB_EMITTER_AT_COLLISION,
+ SUB_EMITTER_MAX
+ };
+
private:
union MaterialKey {
struct {
@@ -78,10 +96,9 @@ private:
uint32_t texture_color : 1;
uint32_t flags : 4;
uint32_t emission_shape : 2;
- uint32_t trail_size_texture : 1;
- uint32_t trail_color_texture : 1;
uint32_t invalid_key : 1;
uint32_t has_emission_color : 1;
+ uint32_t sub_emitter : 2;
};
uint32_t key;
@@ -116,9 +133,8 @@ private:
mk.texture_color = color_ramp.is_valid() ? 1 : 0;
mk.emission_shape = emission_shape;
- mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0;
- mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0;
mk.has_emission_color = emission_shape >= EMISSION_SHAPE_POINTS && emission_color_texture.is_valid();
+ mk.sub_emitter = sub_emitter_mode;
return mk;
}
@@ -178,13 +194,13 @@ private:
StringName emission_texture_normal;
StringName emission_texture_color;
- StringName trail_divisor;
- StringName trail_size_modifier;
- StringName trail_color_modifier;
-
StringName gravity;
StringName lifetime_randomness;
+
+ StringName sub_emitter_frequency;
+ StringName sub_emitter_amount_at_end;
+ StringName sub_emitter_keep_velocity;
};
static ShaderNames *shader_names;
@@ -218,15 +234,14 @@ private:
bool anim_loop;
- int trail_divisor;
-
- Ref<CurveTexture> trail_size_modifier;
- Ref<GradientTexture> trail_color_modifier;
-
Vector3 gravity;
float lifetime_randomness;
+ SubEmitterMode sub_emitter_mode;
+ float sub_emitter_frequency;
+ int sub_emitter_amount_at_end;
+ bool sub_emitter_keep_velocity;
//do not save emission points here
protected:
@@ -277,15 +292,6 @@ public:
Ref<Texture2D> get_emission_color_texture() const;
int get_emission_point_count() const;
- void set_trail_divisor(int p_divisor);
- int get_trail_divisor() const;
-
- void set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier);
- Ref<CurveTexture> get_trail_size_modifier() const;
-
- void set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier);
- Ref<GradientTexture> get_trail_color_modifier() const;
-
void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
@@ -296,6 +302,18 @@ public:
static void finish_shaders();
static void flush_changes();
+ void set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode);
+ SubEmitterMode get_sub_emitter_mode() const;
+
+ void set_sub_emitter_frequency(float p_frequency);
+ float get_sub_emitter_frequency() const;
+
+ void set_sub_emitter_amount_at_end(int p_amount);
+ int get_sub_emitter_amount_at_end() const;
+
+ void set_sub_emitter_keep_velocity(bool p_enable);
+ bool get_sub_emitter_keep_velocity() const;
+
RID get_shader_rid() const;
virtual Shader::Mode get_shader_mode() const override;
@@ -307,5 +325,6 @@ public:
VARIANT_ENUM_CAST(ParticlesMaterial::Parameter)
VARIANT_ENUM_CAST(ParticlesMaterial::Flags)
VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape)
+VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode)
#endif // PARTICLES_MATERIAL_H
diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp
index 2a5cd1101a..59bf8c0e13 100644
--- a/scene/resources/physics_material.cpp
+++ b/scene/resources/physics_material.cpp
@@ -43,9 +43,9 @@ void PhysicsMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_absorbent", "absorbent"), &PhysicsMaterial::set_absorbent);
ClassDB::bind_method(D_METHOD("is_absorbent"), &PhysicsMaterial::is_absorbent);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction"), "set_friction", "get_friction");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rough"), "set_rough", "is_rough");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce"), "set_bounce", "get_bounce");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "absorbent"), "set_absorbent", "is_absorbent");
}
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 4249542567..92f0353abf 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -142,8 +142,6 @@ void Shader::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param);
- //ClassDB::bind_method(D_METHOD("get_param_list"),&Shader::get_fragment_code);
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_code", "get_code");
BIND_ENUM_CONSTANT(MODE_SPATIAL);
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index eb65f10ec9..cdb0ec5111 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -245,6 +245,7 @@ void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) {
region_rect = p_region_rect;
emit_changed();
+ _change_notify("region");
}
Rect2 StyleBoxTexture::get_region_rect() const {
@@ -910,7 +911,7 @@ void StyleBoxFlat::_bind_methods() {
ADD_GROUP("Shadow", "shadow_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size"), "set_shadow_size", "get_shadow_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_shadow_size", "get_shadow_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset"), "set_shadow_offset", "get_shadow_offset");
ADD_GROUP("Anti Aliasing", "anti_aliasing_");
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 4479b822c0..5d58e71fc5 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -53,13 +53,13 @@ Dictionary SyntaxHighlighter::get_line_syntax_highlighting(int p_line) {
return color_map;
}
-void SyntaxHighlighter::_line_edited_from(int p_line) {
+void SyntaxHighlighter::_lines_edited_from(int p_from_line, int p_to_line) {
if (highlighting_cache.size() < 1) {
return;
}
int cache_size = highlighting_cache.back()->key();
- for (int i = p_line - 1; i <= cache_size; i++) {
+ for (int i = MIN(p_from_line, p_to_line) - 1; i <= cache_size; i++) {
if (highlighting_cache.has(i)) {
highlighting_cache.erase(i);
}
@@ -93,7 +93,7 @@ void SyntaxHighlighter::update_cache() {
void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) {
if (text_edit && ObjectDB::get_instance(text_edit_instance_id)) {
- text_edit->disconnect("line_edited_from", callable_mp(this, &SyntaxHighlighter::_line_edited_from));
+ text_edit->disconnect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from));
}
text_edit = p_text_edit;
@@ -101,7 +101,7 @@ void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) {
return;
}
text_edit_instance_id = text_edit->get_instance_id();
- text_edit->connect("line_edited_from", callable_mp(this, &SyntaxHighlighter::_line_edited_from));
+ text_edit->connect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from));
update_cache();
}
@@ -125,11 +125,11 @@ void SyntaxHighlighter::_bind_methods() {
////////////////////////////////////////////////////////////////////////////////
-static bool _is_char(CharType c) {
+static bool _is_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
-static bool _is_hex_symbol(CharType c) {
+static bool _is_hex_symbol(char32_t c) {
return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
@@ -195,7 +195,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
/* search the line */
bool match = true;
- const CharType *start_key = color_regions[c].start_key.c_str();
+ const char32_t *start_key = color_regions[c].start_key.get_data();
for (int k = 0; k < start_key_length; k++) {
if (start_key[k] != str[from + k]) {
match = false;
@@ -229,18 +229,16 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
/* if we are in one find the end key */
if (in_region != -1) {
- /* check there is enough room */
- int chars_left = line_length - from;
- int end_key_length = color_regions[in_region].end_key.length();
- if (chars_left < end_key_length) {
- continue;
- }
-
/* search the line */
int region_end_index = -1;
- const CharType *end_key = color_regions[in_region].start_key.c_str();
+ int end_key_length = color_regions[in_region].end_key.length();
+ const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
- if (!is_a_symbol) {
+ if (line_length - from < end_key_length) {
+ break;
+ }
+
+ if (!is_symbol(str[from])) {
continue;
}
@@ -249,9 +247,10 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
continue;
}
+ region_end_index = from;
for (int k = 0; k < end_key_length; k++) {
- if (end_key[k] == str[from + k]) {
- region_end_index = from;
+ if (end_key[k] != str[from + k]) {
+ region_end_index = -1;
break;
}
}
@@ -265,7 +264,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
highlighter_info["color"] = color_regions[in_region].color;
color_map[j] = highlighter_info;
- j = from;
+ j = from + (end_key_length - 1);
if (region_end_index == -1) {
color_region_cache[p_line] = in_region;
}
@@ -484,8 +483,12 @@ void CodeHighlighter::add_color_region(const String &p_start_key, const String &
}
}
+ int at = 0;
for (int i = 0; i < color_regions.size(); i++) {
ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "color region with start key '" + p_start_key + "' already exists.");
+ if (p_start_key.length() < color_regions[i].start_key.length()) {
+ at++;
+ }
}
ColorRegion color_region;
@@ -493,7 +496,7 @@ void CodeHighlighter::add_color_region(const String &p_start_key, const String &
color_region.start_key = p_start_key;
color_region.end_key = p_end_key;
color_region.line_only = p_line_only || p_end_key == "";
- color_regions.push_back(color_region);
+ color_regions.insert(at, color_region);
clear_highlighting_cache();
}
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
index 40a8870b45..720227a256 100644
--- a/scene/resources/syntax_highlighter.h
+++ b/scene/resources/syntax_highlighter.h
@@ -40,7 +40,7 @@ class SyntaxHighlighter : public Resource {
private:
Map<int, Dictionary> highlighting_cache;
- void _line_edited_from(int p_line);
+ void _lines_edited_from(int p_from_line, int p_to_line);
protected:
ObjectID text_edit_instance_id; // For validity check
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 5681613c04..39237e1a33 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -791,8 +791,312 @@ String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_pa
return "";
}
+////////////////////////////////////
+
+TypedArray<Image> Texture3D::_get_data() const {
+ Vector<Ref<Image>> data = get_data();
+
+ TypedArray<Image> ret;
+ ret.resize(data.size());
+ for (int i = 0; i < data.size(); i++) {
+ ret[i] = data[i];
+ }
+ return ret;
+}
+
+void Texture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format);
+ ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height);
+ ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_data);
+}
//////////////////////////////////////////
+Image::Format ImageTexture3D::get_format() const {
+ return format;
+}
+int ImageTexture3D::get_width() const {
+ return width;
+}
+int ImageTexture3D::get_height() const {
+ return height;
+}
+int ImageTexture3D::get_depth() const {
+ return depth;
+}
+bool ImageTexture3D::has_mipmaps() const {
+ return mipmaps;
+}
+
+Error ImageTexture3D::_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data) {
+ Vector<Ref<Image>> images;
+ images.resize(p_data.size());
+ for (int i = 0; i < images.size(); i++) {
+ images.write[i] = p_data[i];
+ }
+ return create(p_format, p_width, p_height, p_depth, p_mipmaps, images);
+}
+
+void ImageTexture3D::_update(const TypedArray<Image> &p_data) {
+ Vector<Ref<Image>> images;
+ images.resize(p_data.size());
+ for (int i = 0; i < images.size(); i++) {
+ images.write[i] = p_data[i];
+ }
+ return update(images);
+}
+
+Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
+ RID tex = RenderingServer::get_singleton()->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
+ ERR_FAIL_COND_V(tex.is_null(), ERR_CANT_CREATE);
+
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_replace(texture, tex);
+ }
+
+ return OK;
+}
+
+void ImageTexture3D::update(const Vector<Ref<Image>> &p_data) {
+ ERR_FAIL_COND(!texture.is_valid());
+ RenderingServer::get_singleton()->texture_3d_update(texture, p_data);
+}
+
+Vector<Ref<Image>> ImageTexture3D::get_data() const {
+ ERR_FAIL_COND_V(!texture.is_valid(), Vector<Ref<Image>>());
+ return RS::get_singleton()->texture_3d_get(texture);
+}
+
+RID ImageTexture3D::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_3d_placeholder_create();
+ }
+ return texture;
+}
+void ImageTexture3D::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ Resource::set_path(p_path, p_take_over);
+}
+
+void ImageTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create", "format", "width", "height", "depth", "use_mipmaps", "data"), &ImageTexture3D::_create);
+ ClassDB::bind_method(D_METHOD("update", "data"), &ImageTexture3D::_update);
+}
+
+ImageTexture3D::ImageTexture3D() {
+}
+
+ImageTexture3D::~ImageTexture3D() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
+}
+
+////////////////////////////////////////////
+
+void StreamTexture3D::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ Resource::set_path(p_path, p_take_over);
+}
+
+Image::Format StreamTexture3D::get_format() const {
+ return format;
+}
+
+Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) {
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
+ f->get_buffer(header, 4);
+ ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED);
+
+ //stored as stream textures (used for lossless and lossy compression)
+ uint32_t version = f->get_32();
+
+ if (version > FORMAT_VERSION) {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ }
+
+ r_depth = f->get_32(); //depth
+ f->get_32(); //ignored (mode)
+ f->get_32(); // ignored (data format)
+
+ f->get_32(); //ignored
+ int mipmaps = f->get_32();
+ f->get_32(); //ignored
+ f->get_32(); //ignored
+
+ r_mipmaps = mipmaps != 0;
+
+ r_data.clear();
+
+ for (int i = 0; i < (r_depth + mipmaps); i++) {
+ Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0);
+ ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ if (i == 0) {
+ r_format = image->get_format();
+ r_width = image->get_width();
+ r_height = image->get_height();
+ }
+ r_data.push_back(image);
+ }
+
+ return OK;
+}
+
+Error StreamTexture3D::load(const String &p_path) {
+ Vector<Ref<Image>> data;
+
+ int tw, th, td;
+ Image::Format tfmt;
+ bool tmm;
+
+ Error err = _load_data(p_path, data, tfmt, tw, th, td, tmm);
+ if (err) {
+ return err;
+ }
+
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
+ }
+
+ w = tw;
+ h = th;
+ d = td;
+ mipmaps = tmm;
+ format = tfmt;
+
+ path_to_file = p_path;
+
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
+
+ _change_notify();
+ emit_changed();
+ return OK;
+}
+
+String StreamTexture3D::get_load_path() const {
+ return path_to_file;
+}
+
+int StreamTexture3D::get_width() const {
+ return w;
+}
+
+int StreamTexture3D::get_height() const {
+ return h;
+}
+
+int StreamTexture3D::get_depth() const {
+ return d;
+}
+
+bool StreamTexture3D::has_mipmaps() const {
+ return mipmaps;
+}
+
+RID StreamTexture3D::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_3d_placeholder_create();
+ }
+ return texture;
+}
+
+Vector<Ref<Image>> StreamTexture3D::get_data() const {
+ if (texture.is_valid()) {
+ return RS::get_singleton()->texture_3d_get(texture);
+ } else {
+ return Vector<Ref<Image>>();
+ }
+}
+
+void StreamTexture3D::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ path = ResourceLoader::path_remap(path); //remap for translation
+ path = ResourceLoader::import_remap(path); //remap for import
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ load(path);
+}
+
+void StreamTexture3D::_validate_property(PropertyInfo &property) const {
+}
+
+void StreamTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+}
+
+StreamTexture3D::StreamTexture3D() {
+ format = Image::FORMAT_MAX;
+ w = 0;
+ h = 0;
+ d = 0;
+ mipmaps = false;
+}
+
+StreamTexture3D::~StreamTexture3D() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
+}
+
+/////////////////////////////
+
+RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTexture3D> st;
+ st.instance();
+ Error err = st->load(p_path);
+ if (r_error) {
+ *r_error = err;
+ }
+ if (err != OK) {
+ return RES();
+ }
+
+ return st;
+}
+
+void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("stex3d");
+}
+
+bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture3D";
+}
+
+String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stex3d") {
+ return "StreamTexture3D";
+ }
+ return "";
+}
+
+////////////////////////////////////////////
+
int AtlasTexture::get_width() const {
if (region.size.width == 0) {
if (atlas.is_valid()) {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index d439d34c95..eebbf4f233 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -515,6 +515,122 @@ public:
virtual String get_resource_type(const String &p_path) const;
};
+class Texture3D : public Texture {
+ GDCLASS(Texture3D, Texture);
+
+protected:
+ static void _bind_methods();
+
+ TypedArray<Image> _get_data() const;
+
+public:
+ virtual Image::Format get_format() const = 0;
+ virtual int get_width() const = 0;
+ virtual int get_height() const = 0;
+ virtual int get_depth() const = 0;
+ virtual bool has_mipmaps() const = 0;
+ virtual Vector<Ref<Image>> get_data() const = 0;
+};
+
+class ImageTexture3D : public Texture3D {
+ GDCLASS(ImageTexture3D, Texture3D);
+
+ mutable RID texture;
+
+ Image::Format format = Image::FORMAT_MAX;
+ int width = 1;
+ int height = 1;
+ int depth = 1;
+ bool mipmaps = false;
+
+protected:
+ static void _bind_methods();
+
+ Error _create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
+ void _update(const TypedArray<Image> &p_data);
+
+public:
+ virtual Image::Format get_format() const override;
+ virtual int get_width() const override;
+ virtual int get_height() const override;
+ virtual int get_depth() const override;
+ virtual bool has_mipmaps() const override;
+
+ Error create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data);
+ void update(const Vector<Ref<Image>> &p_data);
+ virtual Vector<Ref<Image>> get_data() const override;
+
+ virtual RID get_rid() const override;
+ virtual void set_path(const String &p_path, bool p_take_over = false) override;
+
+ ImageTexture3D();
+ ~ImageTexture3D();
+};
+
+class StreamTexture3D : public Texture3D {
+ GDCLASS(StreamTexture3D, Texture3D);
+
+public:
+ enum DataFormat {
+ DATA_FORMAT_IMAGE,
+ DATA_FORMAT_LOSSLESS,
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
+
+ enum {
+ FORMAT_VERSION = 1
+ };
+
+ enum FormatBits {
+ FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1,
+ FORMAT_BIT_LOSSLESS = 1 << 20,
+ FORMAT_BIT_LOSSY = 1 << 21,
+ FORMAT_BIT_STREAM = 1 << 22,
+ FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
+ };
+
+private:
+ Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps);
+ String path_to_file;
+ mutable RID texture;
+ Image::Format format;
+ int w, h, d;
+ bool mipmaps;
+
+ virtual void reload_from_file() override;
+
+protected:
+ static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
+
+public:
+ Image::Format get_format() const override;
+ Error load(const String &p_path);
+ String get_load_path() const;
+
+ int get_width() const override;
+ int get_height() const override;
+ int get_depth() const override;
+ virtual bool has_mipmaps() const override;
+ virtual RID get_rid() const override;
+
+ virtual void set_path(const String &p_path, bool p_take_over) override;
+
+ virtual Vector<Ref<Image>> get_data() const override;
+
+ StreamTexture3D();
+ ~StreamTexture3D();
+};
+
+class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual 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 CurveTexture : public Texture2D {
GDCLASS(CurveTexture, Texture2D);
RES_BASE_EXTENSION("curvetex")
@@ -632,11 +748,12 @@ class AnimatedTexture : public Texture2D {
//use readers writers lock for this, since its far more times read than written to
RWLock *rw_lock;
-private:
+public:
enum {
MAX_FRAMES = 256
};
+private:
RID proxy_ph;
RID proxy;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 6992360df7..84b067d1e2 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -40,7 +40,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
if (slash == -1) {
return false;
}
- int id = String::to_int(n.c_str(), slash);
+ int id = String::to_int(n.get_data(), slash);
if (!tile_map.has(id)) {
create_tile(id);
@@ -216,7 +216,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
if (slash == -1) {
return false;
}
- int id = String::to_int(n.c_str(), slash);
+ int id = String::to_int(n.get_data(), slash);
ERR_FAIL_COND_V(!tile_map.has(id), false);
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index e4851ad9f7..b8d2003e68 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -101,6 +101,14 @@ bool VisualShaderNode::is_code_generated() const {
return true;
}
+bool VisualShaderNode::is_show_prop_names() const {
+ return false;
+}
+
+bool VisualShaderNode::is_use_prop_slots() const {
+ return false;
+}
+
Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
return Vector<VisualShader::DefaultTextureParam>();
}
@@ -172,8 +180,6 @@ void VisualShaderNode::_bind_methods() {
}
VisualShaderNode::VisualShaderNode() {
- port_preview = -1;
- simple_decl = true;
}
/////////////////////////////////////////////////////////
@@ -319,6 +325,14 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() {
/////////////////////////////////////////////////////////
+void VisualShader::set_shader_type(Type p_type) {
+ current_type = p_type;
+}
+
+VisualShader::Type VisualShader::get_shader_type() const {
+ return current_type;
+}
+
void VisualShader::set_version(const String &p_version) {
version = p_version;
}
@@ -920,8 +934,12 @@ VisualShader::RenderModeEnums VisualShader::render_mode_enums[] = {
static const char *type_string[VisualShader::TYPE_MAX] = {
"vertex",
"fragment",
- "light"
+ "light",
+ "emit",
+ "process",
+ "end"
};
+
bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
if (name == "mode") {
@@ -1344,6 +1362,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
return OK;
}
+bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const {
+ if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) {
+ if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) {
+ if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return true;
+}
+
void VisualShader::_update_shader() const {
if (!dirty) {
return;
@@ -1367,10 +1398,19 @@ void VisualShader::_update_shader() const {
{
//fill render mode enums
int idx = 0;
+ bool specular = false;
while (render_mode_enums[idx].string) {
if (shader_mode == render_mode_enums[idx].mode) {
- if (modes.has(render_mode_enums[idx].string)) {
- int which = modes[render_mode_enums[idx].string];
+ if (shader_mode == Shader::MODE_SPATIAL) {
+ if (String(render_mode_enums[idx].string) == "specular") {
+ specular = true;
+ }
+ }
+ if (modes.has(render_mode_enums[idx].string) || specular) {
+ int which = 0;
+ if (modes.has(render_mode_enums[idx].string)) {
+ which = modes[render_mode_enums[idx].string];
+ }
int count = 0;
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
@@ -1406,14 +1446,14 @@ void VisualShader::_update_shader() const {
global_code += "render_mode " + render_mode + ";\n\n";
}
- static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" };
+ static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end" };
String global_expressions;
Set<String> used_uniform_names;
List<VisualShaderNodeUniform *> uniforms;
for (int i = 0, index = 0; i < TYPE_MAX; i++) {
- if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
continue;
}
@@ -1448,8 +1488,10 @@ void VisualShader::_update_shader() const {
}
}
+ Map<int, String> code_map;
+
for (int i = 0; i < TYPE_MAX; i++) {
- if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
continue;
}
@@ -1457,6 +1499,8 @@ void VisualShader::_update_shader() const {
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
+ StringBuilder func_code;
+
for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
ConnectionKey from_key;
from_key.node = E->get().from_node;
@@ -1470,14 +1514,30 @@ void VisualShader::_update_shader() const {
input_connections.insert(to_key, E);
}
-
- code += "\nvoid " + String(func_name[i]) + "() {\n";
+ if (shader_mode != Shader::MODE_PARTICLES) {
+ func_code += "\nvoid " + String(func_name[i]) + "() {\n";
+ }
+ insertion_pos.insert(i, code.get_string_length() + func_code.get_string_length());
Set<int> processed;
- 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);
+ Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
ERR_FAIL_COND(err != OK);
- insertion_pos.insert(i, code.get_string_length());
+ if (shader_mode == Shader::MODE_PARTICLES) {
+ code_map.insert(i, func_code);
+ } else {
+ func_code += "}\n";
+ code += func_code;
+ }
+ }
+
+ if (shader_mode == Shader::MODE_PARTICLES) {
+ code += "\nvoid compute() {\n";
+ code += "\tif (RESTART) {\n";
+ code += code_map[TYPE_EMIT];
+ code += "\t} else {\n";
+ code += code_map[TYPE_PROCESS];
+ code += "\t}\n";
code += "}\n";
}
@@ -1488,7 +1548,7 @@ void VisualShader::_update_shader() const {
final_code += global_expressions;
String tcode = code;
for (int i = 0; i < TYPE_MAX; i++) {
- if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) {
+ if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
continue;
}
tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]);
@@ -1567,9 +1627,14 @@ void VisualShader::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version");
+ ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs.
+
BIND_ENUM_CONSTANT(TYPE_VERTEX);
BIND_ENUM_CONSTANT(TYPE_FRAGMENT);
BIND_ENUM_CONSTANT(TYPE_LIGHT);
+ BIND_ENUM_CONSTANT(TYPE_EMIT);
+ BIND_ENUM_CONSTANT(TYPE_PROCESS);
+ BIND_ENUM_CONSTANT(TYPE_END);
BIND_ENUM_CONSTANT(TYPE_MAX);
BIND_CONSTANT(NODE_ID_INVALID);
@@ -1577,8 +1642,6 @@ void VisualShader::_bind_methods() {
}
VisualShader::VisualShader() {
- shader_mode = Shader::MODE_SPATIAL;
-
for (int i = 0; i < TYPE_MAX; i++) {
Ref<VisualShaderNodeOutput> output;
output.instance();
@@ -1587,8 +1650,6 @@ VisualShader::VisualShader() {
graph[i].nodes[NODE_ID_OUTPUT].node = output;
graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150);
}
-
- dirty = true;
}
///////////////////////////////////////////////////////////
@@ -1711,22 +1772,50 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
- // Particles, Vertex
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
-
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
-
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ // Particles, Emit
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ // Particles, Process
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+
+ // Particles, End
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Sky, Fragment
{ Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" },
@@ -2028,10 +2117,6 @@ void VisualShaderNodeInput::_bind_methods() {
}
VisualShaderNodeInput::VisualShaderNodeInput() {
- input_name = "[None]";
- // changed when set
- shader_type = VisualShader::TYPE_MAX;
- shader_mode = Shader::MODE_MAX;
}
////////////// UniformRef
@@ -2046,6 +2131,15 @@ void VisualShaderNodeUniformRef::clear_uniforms() {
uniforms.clear();
}
+bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) {
+ for (List<VisualShaderNodeUniformRef::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().name == p_name) {
+ return true;
+ }
+ }
+ return false;
+}
+
String VisualShaderNodeUniformRef::get_caption() const {
return "UniformRef";
}
@@ -2063,10 +2157,6 @@ String VisualShaderNodeUniformRef::get_input_port_name(int p_port) const {
}
int VisualShaderNodeUniformRef::get_output_port_count() const {
- if (uniform_name == "[None]") {
- return 0;
- }
-
switch (uniform_type) {
case UniformType::UNIFORM_TYPE_FLOAT:
return 1;
@@ -2085,7 +2175,7 @@ int VisualShaderNodeUniformRef::get_output_port_count() const {
default:
break;
}
- return 0;
+ return 1;
}
VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port_type(int p_port) const {
@@ -2145,8 +2235,8 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const {
void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) {
uniform_name = p_name;
- if (p_name != "[None]") {
- uniform_type = get_uniform_type_by_name(p_name);
+ if (uniform_name != "[None]") {
+ uniform_type = get_uniform_type_by_name(uniform_name);
} else {
uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
}
@@ -2187,6 +2277,9 @@ VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_
String VisualShaderNodeUniformRef::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 {
switch (uniform_type) {
case UniformType::UNIFORM_TYPE_FLOAT:
+ if (uniform_name == "[None]") {
+ return "\t" + p_output_vars[0] + " = 0.0;\n";
+ }
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
case UniformType::UNIFORM_TYPE_INT:
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
@@ -2209,22 +2302,33 @@ String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShad
return "";
}
+void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) {
+ uniform_type = (UniformType)p_uniform_type;
+}
+
+int VisualShaderNodeUniformRef::_get_uniform_type() const {
+ return (int)uniform_type;
+}
+
void VisualShaderNodeUniformRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniformRef::set_uniform_name);
ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniformRef::get_uniform_name);
+ ClassDB::bind_method(D_METHOD("_set_uniform_type", "type"), &VisualShaderNodeUniformRef::_set_uniform_type);
+ ClassDB::bind_method(D_METHOD("_get_uniform_type"), &VisualShaderNodeUniformRef::_get_uniform_type);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name", PROPERTY_HINT_ENUM, ""), "set_uniform_name", "get_uniform_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "uniform_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_uniform_type", "_get_uniform_type");
}
Vector<StringName> VisualShaderNodeUniformRef::get_editable_properties() const {
Vector<StringName> props;
props.push_back("uniform_name");
+ props.push_back("uniform_type");
return props;
}
VisualShaderNodeUniformRef::VisualShaderNodeUniformRef() {
- uniform_name = "[None]";
- uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
}
////////////////////////////////////////////
@@ -2283,13 +2387,30 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" },
- // Particles, Vertex
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
- { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ // Particles, Emit
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
+ // Particles, Process
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
+ // Particles, End
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" },
+ { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" },
// Sky, Fragment
{ Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" },
{ Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" },
@@ -2477,7 +2598,6 @@ Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const {
}
VisualShaderNodeUniform::VisualShaderNodeUniform() {
- qualifier = QUAL_NONE;
}
////////////// GroupBase
@@ -2609,6 +2729,7 @@ void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const Strin
}
_apply_port_changes();
+ emit_changed();
}
void VisualShaderNodeGroupBase::remove_input_port(int p_id) {
@@ -2633,6 +2754,7 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) {
}
_apply_port_changes();
+ emit_changed();
}
int VisualShaderNodeGroupBase::get_input_port_count() const {
@@ -2677,6 +2799,7 @@ void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const Stri
}
_apply_port_changes();
+ emit_changed();
}
void VisualShaderNodeGroupBase::remove_output_port(int p_id) {
@@ -2701,6 +2824,7 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) {
}
_apply_port_changes();
+ emit_changed();
}
int VisualShaderNodeGroupBase::get_output_port_count() const {
@@ -2747,6 +2871,7 @@ void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) {
inputs = inputs.insert(index, itos(p_type));
_apply_port_changes();
+ emit_changed();
}
VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_input_port_type(int p_id) const {
@@ -2782,6 +2907,7 @@ void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_na
inputs = inputs.insert(index, p_name);
_apply_port_changes();
+ emit_changed();
}
String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const {
@@ -2817,6 +2943,7 @@ void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) {
outputs = outputs.insert(index, itos(p_type));
_apply_port_changes();
+ emit_changed();
}
VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_output_port_type(int p_id) const {
@@ -2852,6 +2979,7 @@ void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_n
outputs = outputs.insert(index, p_name);
_apply_port_changes();
+ emit_changed();
}
String VisualShaderNodeGroupBase::get_output_port_name(int p_id) const {
@@ -2951,10 +3079,6 @@ String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShade
}
VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() {
- size = Size2(0, 0);
- inputs = "";
- outputs = "";
- editable = false;
simple_decl = false;
}
@@ -2966,6 +3090,7 @@ String VisualShaderNodeExpression::get_caption() const {
void VisualShaderNodeExpression::set_expression(const String &p_expression) {
expression = p_expression;
+ emit_changed();
}
String VisualShaderNodeExpression::get_expression() const {
@@ -3079,7 +3204,6 @@ void VisualShaderNodeExpression::_bind_methods() {
}
VisualShaderNodeExpression::VisualShaderNodeExpression() {
- expression = "";
set_editable(true);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 05d8950be9..e7d74b6c17 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -50,6 +50,9 @@ public:
TYPE_VERTEX,
TYPE_FRAGMENT,
TYPE_LIGHT,
+ TYPE_EMIT,
+ TYPE_PROCESS,
+ TYPE_END,
TYPE_MAX
};
@@ -66,6 +69,8 @@ public:
};
private:
+ Type current_type;
+
struct Node {
Ref<VisualShaderNode> node;
Vector2 position;
@@ -77,7 +82,7 @@ private:
List<Connection> connections;
} graph[TYPE_MAX];
- Shader::Mode shader_mode;
+ Shader::Mode shader_mode = Shader::MODE_SPATIAL;
mutable String previous_code;
Array _get_node_connections(Type p_type) const;
@@ -94,7 +99,7 @@ private:
static RenderModeEnums render_mode_enums[];
- volatile mutable bool dirty;
+ volatile mutable bool dirty = true;
void _queue_update();
union ConnectionKey {
@@ -111,6 +116,7 @@ private:
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);
+ bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
protected:
virtual void _update_shader() const override;
@@ -120,6 +126,10 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+public: // internal methods
+ void set_shader_type(Type p_type);
+ Type get_shader_type() const;
+
public:
void set_version(const String &p_version);
String get_version() const;
@@ -179,7 +189,7 @@ VARIANT_ENUM_CAST(VisualShader::Type)
class VisualShaderNode : public Resource {
GDCLASS(VisualShaderNode, Resource);
- int port_preview;
+ int port_preview = -1;
Map<int, Variant> default_input_values;
Map<int, bool> connected_input_ports;
@@ -187,7 +197,7 @@ class VisualShaderNode : public Resource {
int connected_output_count = 0;
protected:
- bool simple_decl;
+ bool simple_decl = true;
static void _bind_methods();
public:
@@ -232,6 +242,8 @@ public:
virtual bool is_generate_input_var(int p_port) const;
virtual bool is_code_generated() const;
+ virtual bool is_show_prop_names() const;
+ virtual bool is_use_prop_slots() const;
virtual Vector<StringName> get_editable_properties() const;
@@ -289,8 +301,8 @@ class VisualShaderNodeInput : public VisualShaderNode {
GDCLASS(VisualShaderNodeInput, VisualShaderNode);
friend class VisualShader;
- VisualShader::Type shader_type;
- Shader::Mode shader_mode;
+ VisualShader::Type shader_type = VisualShader::TYPE_MAX;
+ Shader::Mode shader_mode = Shader::MODE_MAX;
struct Port {
Shader::Mode mode;
@@ -303,7 +315,7 @@ class VisualShaderNodeInput : public VisualShaderNode {
static const Port ports[];
static const Port preview_ports[];
- String input_name;
+ String input_name = "[None]";
protected:
static void _bind_methods();
@@ -387,8 +399,8 @@ public:
};
private:
- String uniform_name;
- Qualifier qualifier;
+ String uniform_name = "";
+ Qualifier qualifier = QUAL_NONE;
bool global_code_generated = false;
protected:
@@ -435,8 +447,8 @@ public:
};
private:
- String uniform_name;
- UniformType uniform_type;
+ String uniform_name = "[None]";
+ UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT;
protected:
static void _bind_methods();
@@ -444,6 +456,7 @@ protected:
public:
static void add_uniform(const String &p_name, UniformType p_type);
static void clear_uniforms();
+ static bool has_uniform(const String &p_name);
public:
virtual String get_caption() const override;
@@ -459,6 +472,9 @@ public:
void set_uniform_name(const String &p_name);
String get_uniform_name() const;
+ void _set_uniform_type(int p_uniform_type);
+ int _get_uniform_type() const;
+
int get_uniforms_count() const;
String get_uniform_name_by_index(int p_idx) const;
UniformType get_uniform_type_by_name(const String &p_name) const;
@@ -478,10 +494,10 @@ private:
void _apply_port_changes();
protected:
- Vector2 size;
- String inputs;
- String outputs;
- bool editable;
+ Vector2 size = Size2(0, 0);
+ String inputs = "";
+ String outputs = "";
+ bool editable = false;
struct Port {
PortType type;
@@ -549,7 +565,7 @@ class VisualShaderNodeExpression : public VisualShaderNodeGroupBase {
GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase);
protected:
- String expression;
+ String expression = "";
static void _bind_methods();
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index b0c871bc71..cffe0bb5cd 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -87,7 +87,6 @@ void VisualShaderNodeFloatConstant::_bind_methods() {
}
VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() {
- constant = 0.0;
}
////////////// Scalar(Int)
@@ -147,7 +146,6 @@ void VisualShaderNodeIntConstant::_bind_methods() {
}
VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() {
- constant = 0;
}
////////////// Boolean
@@ -207,7 +205,6 @@ void VisualShaderNodeBooleanConstant::_bind_methods() {
}
VisualShaderNodeBooleanConstant::VisualShaderNodeBooleanConstant() {
- constant = false;
}
////////////// Color
@@ -271,7 +268,6 @@ void VisualShaderNodeColorConstant::_bind_methods() {
}
VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() {
- constant = Color(1, 1, 1, 1);
}
////////////// Vector
@@ -777,8 +773,6 @@ void VisualShaderNodeTexture::_bind_methods() {
}
VisualShaderNodeTexture::VisualShaderNodeTexture() {
- texture_type = TYPE_DATA;
- source = SOURCE_TEXTURE;
}
////////////// Sample3D
@@ -898,7 +892,6 @@ String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::
}
VisualShaderNodeSample3D::VisualShaderNodeSample3D() {
- source = SOURCE_TEXTURE;
simple_decl = false;
}
@@ -958,6 +951,64 @@ void VisualShaderNodeTexture2DArray::_bind_methods() {
VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() {
}
+
+////////////// Texture3D
+
+String VisualShaderNodeTexture3D::get_caption() const {
+ return "Texture3D";
+}
+
+String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const {
+ if (p_port == 2) {
+ return "sampler3D";
+ }
+ return VisualShaderNodeSample3D::get_input_port_name(p_port);
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "tex3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ if (source == SOURCE_TEXTURE) {
+ return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n";
+ }
+ return String();
+}
+
+void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_value) {
+ texture = p_value;
+ emit_changed();
+}
+
+Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("source");
+ if (source == SOURCE_TEXTURE) {
+ props.push_back("texture");
+ }
+ return props;
+}
+
+void VisualShaderNodeTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture");
+}
+
+VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() {
+}
+
////////////// Cubemap
String VisualShaderNodeCubemap::get_caption() const {
@@ -1143,8 +1194,6 @@ void VisualShaderNodeCubemap::_bind_methods() {
}
VisualShaderNodeCubemap::VisualShaderNodeCubemap() {
- texture_type = TYPE_DATA;
- source = SOURCE_TEXTURE;
simple_decl = false;
}
@@ -1250,7 +1299,6 @@ void VisualShaderNodeFloatOp::_bind_methods() {
}
VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() {
- op = OP_ADD;
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
}
@@ -1345,7 +1393,6 @@ void VisualShaderNodeIntOp::_bind_methods() {
}
VisualShaderNodeIntOp::VisualShaderNodeIntOp() {
- op = OP_ADD;
set_input_port_default_value(0, 0);
set_input_port_default_value(1, 0);
}
@@ -1460,7 +1507,6 @@ void VisualShaderNodeVectorOp::_bind_methods() {
}
VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() {
- op = OP_ADD;
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
}
@@ -1628,7 +1674,6 @@ void VisualShaderNodeColorOp::_bind_methods() {
}
VisualShaderNodeColorOp::VisualShaderNodeColorOp() {
- op = OP_SCREEN;
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
}
@@ -1703,7 +1748,6 @@ void VisualShaderNodeTransformMult::_bind_methods() {
}
VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() {
- op = OP_AxB;
set_input_port_default_value(0, Transform());
set_input_port_default_value(1, Transform());
}
@@ -1778,7 +1822,6 @@ void VisualShaderNodeTransformVecMult::_bind_methods() {
}
VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() {
- op = OP_AxB;
set_input_port_default_value(0, Transform());
set_input_port_default_value(1, Vector3());
}
@@ -1908,7 +1951,6 @@ void VisualShaderNodeFloatFunc::_bind_methods() {
}
VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() {
- func = FUNC_SIGN;
set_input_port_default_value(0, 0.0);
}
@@ -2003,7 +2045,6 @@ void VisualShaderNodeIntFunc::_bind_methods() {
}
VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() {
- func = FUNC_SIGN;
set_input_port_default_value(0, 0);
}
@@ -2169,7 +2210,6 @@ void VisualShaderNodeVectorFunc::_bind_methods() {
}
VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
- func = FUNC_NORMALIZE;
set_input_port_default_value(0, Vector3());
}
@@ -2256,9 +2296,8 @@ void VisualShaderNodeColorFunc::_bind_methods() {
}
VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() {
- func = FUNC_GRAYSCALE;
- set_input_port_default_value(0, Vector3());
simple_decl = false;
+ set_input_port_default_value(0, Vector3());
}
////////////// Transform Func
@@ -2328,7 +2367,6 @@ void VisualShaderNodeTransformFunc::_bind_methods() {
}
VisualShaderNodeTransformFunc::VisualShaderNodeTransformFunc() {
- func = FUNC_INVERSE;
set_input_port_default_value(0, Transform());
}
@@ -2516,7 +2554,6 @@ void VisualShaderNodeScalarDerivativeFunc::_bind_methods() {
}
VisualShaderNodeScalarDerivativeFunc::VisualShaderNodeScalarDerivativeFunc() {
- func = FUNC_SUM;
set_input_port_default_value(0, 0.0);
}
@@ -2589,7 +2626,6 @@ void VisualShaderNodeVectorDerivativeFunc::_bind_methods() {
}
VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() {
- func = FUNC_SUM;
set_input_port_default_value(0, Vector3());
}
@@ -3454,6 +3490,14 @@ String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualSh
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeFloatUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeFloatUniform::is_use_prop_slots() const {
+ return true;
+}
+
void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) {
hint = p_hint;
emit_changed();
@@ -3561,12 +3605,6 @@ Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const
}
VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() {
- hint = HINT_NONE;
- hint_range_min = 0.0;
- hint_range_max = 1.0;
- hint_range_step = 0.1;
- default_value_enabled = false;
- default_value = 0.0;
}
////////////// Integer Uniform
@@ -3619,6 +3657,14 @@ String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShad
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeIntUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeIntUniform::is_use_prop_slots() const {
+ return true;
+}
+
void VisualShaderNodeIntUniform::set_hint(Hint p_hint) {
hint = p_hint;
emit_changed();
@@ -3726,12 +3772,6 @@ Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
}
VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() {
- hint = HINT_NONE;
- hint_range_min = 0;
- hint_range_max = 100;
- hint_range_step = 1;
- default_value_enabled = false;
- default_value = 0;
}
////////////// Boolean Uniform
@@ -3799,6 +3839,14 @@ String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, Visual
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeBooleanUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeBooleanUniform::is_use_prop_slots() const {
+ return true;
+}
+
void VisualShaderNodeBooleanUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled);
ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled);
@@ -3824,8 +3872,6 @@ Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() con
}
VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() {
- default_value_enabled = false;
- default_value = false;
}
////////////// Color Uniform
@@ -3891,6 +3937,10 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh
return code;
}
+bool VisualShaderNodeColorUniform::is_show_prop_names() const {
+ return true;
+}
+
void VisualShaderNodeColorUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled);
ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled);
@@ -3916,8 +3966,6 @@ Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const
}
VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
- default_value_enabled = false;
- default_value = Color(1.0, 1.0, 1.0, 1.0);
}
////////////// Vector Uniform
@@ -3992,6 +4040,14 @@ void VisualShaderNodeVec3Uniform::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value");
}
+bool VisualShaderNodeVec3Uniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeVec3Uniform::is_use_prop_slots() const {
+ return true;
+}
+
bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const {
return true; // all qualifiers are supported
}
@@ -4006,8 +4062,6 @@ Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const
}
VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
- default_value_enabled = false;
- default_value = Vector3(0.0, 0.0, 0.0);
}
////////////// Transform Uniform
@@ -4086,6 +4140,14 @@ void VisualShaderNodeTransformUniform::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "default_value"), "set_default_value", "get_default_value");
}
+bool VisualShaderNodeTransformUniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeTransformUniform::is_use_prop_slots() const {
+ return true;
+}
+
bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const {
return true; // all qualifiers are supported
}
@@ -4100,8 +4162,6 @@ Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() c
}
VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
- default_value_enabled = false;
- default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
}
////////////// Texture Uniform
@@ -4271,8 +4331,6 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co
}
VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
- texture_type = TYPE_DATA;
- color_default = COLOR_DEFAULT_WHITE;
simple_decl = false;
}
@@ -4345,13 +4403,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod
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";
+ 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";
+ 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";
+ 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\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";
@@ -4441,6 +4499,74 @@ String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode,
VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() {
}
+////////////// Texture3D Uniform
+
+String VisualShaderNodeTexture3DUniform::get_caption() const {
+ return "Texture3DUniform";
+}
+
+int VisualShaderNodeTexture3DUniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SAMPLER;
+}
+
+String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const {
+ return "sampler3D";
+}
+
+int VisualShaderNodeTexture3DUniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name();
+
+ switch (texture_type) {
+ case TYPE_DATA:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black;\n";
+ else
+ code += ";\n";
+ break;
+ case TYPE_COLOR:
+ if (color_default == COLOR_DEFAULT_BLACK)
+ code += " : hint_black_albedo;\n";
+ else
+ code += " : hint_albedo;\n";
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
+ break;
+ }
+
+ return code;
+}
+
+String VisualShaderNodeTexture3DUniform::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 String();
+}
+
+VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() {
+}
+
////////////// Cubemap Uniform
String VisualShaderNodeCubemapUniform::get_caption() const {
@@ -4577,13 +4703,13 @@ String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type
}
VisualShaderNodeIf::VisualShaderNodeIf() {
+ simple_decl = false;
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, CMP_EPSILON);
set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0));
- simple_decl = false;
}
////////////// Switch
@@ -4642,10 +4768,10 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::
}
VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
+ simple_decl = false;
set_input_port_default_value(0, false);
set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
- simple_decl = false;
}
////////////// Switch(scalar)
@@ -4836,7 +4962,6 @@ void VisualShaderNodeIs::_bind_methods() {
}
VisualShaderNodeIs::VisualShaderNodeIs() {
- func = FUNC_IS_INF;
set_input_port_default_value(0, 0.0);
}
@@ -5072,9 +5197,6 @@ void VisualShaderNodeCompare::_bind_methods() {
}
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);
@@ -5167,7 +5289,6 @@ void VisualShaderNodeMultiplyAdd::_bind_methods() {
}
VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() {
- type = TYPE_SCALAR;
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, 0.0);
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index b9c40d0521..1c986d1ef4 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -39,7 +39,7 @@
class VisualShaderNodeFloatConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode);
- float constant;
+ float constant = 0.0f;
protected:
static void _bind_methods();
@@ -69,7 +69,7 @@ public:
class VisualShaderNodeIntConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode);
- int constant;
+ int constant = 0;
protected:
static void _bind_methods();
@@ -99,7 +99,7 @@ public:
class VisualShaderNodeBooleanConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNode);
- bool constant;
+ bool constant = false;
protected:
static void _bind_methods();
@@ -129,7 +129,7 @@ public:
class VisualShaderNodeColorConstant : public VisualShaderNode {
GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode);
- Color constant;
+ Color constant = Color(1, 1, 1, 1);
protected:
static void _bind_methods();
@@ -240,8 +240,8 @@ public:
};
private:
- Source source;
- TextureType texture_type;
+ Source source = SOURCE_TEXTURE;
+ TextureType texture_type = TYPE_DATA;
protected:
static void _bind_methods();
@@ -294,7 +294,7 @@ public:
};
protected:
- Source source;
+ Source source = SOURCE_TEXTURE;
static void _bind_methods();
@@ -343,6 +343,29 @@ public:
VisualShaderNodeTexture2DArray();
};
+class VisualShaderNodeTexture3D : public VisualShaderNodeSample3D {
+ GDCLASS(VisualShaderNodeTexture3D, VisualShaderNodeSample3D);
+ Ref<Texture3D> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+
+ void set_texture(Ref<Texture3D> p_value);
+ Ref<Texture3D> get_texture() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeTexture3D();
+};
+
class VisualShaderNodeCubemap : public VisualShaderNode {
GDCLASS(VisualShaderNodeCubemap, VisualShaderNode);
Ref<Cubemap> cube_map;
@@ -360,8 +383,8 @@ public:
};
private:
- Source source;
- TextureType texture_type;
+ Source source = SOURCE_TEXTURE;
+ TextureType texture_type = TYPE_DATA;
protected:
static void _bind_methods();
@@ -421,7 +444,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_ADD;
static void _bind_methods();
@@ -463,7 +486,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_ADD;
static void _bind_methods();
@@ -510,7 +533,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_ADD;
static void _bind_methods();
@@ -556,7 +579,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_SCREEN;
static void _bind_methods();
@@ -599,7 +622,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_AxB;
static void _bind_methods();
@@ -642,7 +665,7 @@ public:
};
protected:
- Operator op;
+ Operator op = OP_AxB;
static void _bind_methods();
@@ -713,7 +736,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SIGN;
static void _bind_methods();
@@ -756,7 +779,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SIGN;
static void _bind_methods();
@@ -830,7 +853,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_NORMALIZE;
static void _bind_methods();
@@ -871,7 +894,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_GRAYSCALE;
static void _bind_methods();
@@ -912,7 +935,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_INVERSE;
static void _bind_methods();
@@ -1067,7 +1090,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SUM;
static void _bind_methods();
@@ -1107,7 +1130,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_SUM;
static void _bind_methods();
@@ -1482,12 +1505,12 @@ public:
};
private:
- Hint hint;
- float hint_range_min;
- float hint_range_max;
- float hint_range_step;
- bool default_value_enabled;
- float default_value;
+ Hint hint = HINT_NONE;
+ float hint_range_min = 0.0f;
+ float hint_range_max = 1.0f;
+ float hint_range_step = 0.1f;
+ bool default_value_enabled = false;
+ float default_value = 0.0f;
protected:
static void _bind_methods();
@@ -1506,6 +1529,9 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
void set_hint(Hint p_hint);
Hint get_hint() const;
@@ -1544,12 +1570,12 @@ public:
};
private:
- Hint hint;
- int hint_range_min;
- int hint_range_max;
- int hint_range_step;
- bool default_value_enabled;
- int default_value;
+ Hint hint = HINT_NONE;
+ int hint_range_min = 0;
+ int hint_range_max = 100;
+ int hint_range_step = 1;
+ bool default_value_enabled = false;
+ int default_value = 0;
protected:
static void _bind_methods();
@@ -1568,6 +1594,9 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
void set_hint(Hint p_hint);
Hint get_hint() const;
@@ -1601,8 +1630,8 @@ class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform);
private:
- bool default_value_enabled;
- bool default_value;
+ bool default_value_enabled = false;
+ bool default_value = false;
protected:
static void _bind_methods();
@@ -1621,6 +1650,9 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
void set_default_value_enabled(bool p_enabled);
bool is_default_value_enabled() const;
@@ -1640,8 +1672,8 @@ class VisualShaderNodeColorUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform);
private:
- bool default_value_enabled;
- Color default_value;
+ bool default_value_enabled = false;
+ Color default_value = Color(1.0, 1.0, 1.0, 1.0);
protected:
static void _bind_methods();
@@ -1660,6 +1692,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+
void set_default_value_enabled(bool p_enabled);
bool is_default_value_enabled() const;
@@ -1679,7 +1713,7 @@ class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform);
private:
- bool default_value_enabled;
+ bool default_value_enabled = false;
Vector3 default_value;
protected:
@@ -1699,6 +1733,9 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
void set_default_value_enabled(bool p_enabled);
bool is_default_value_enabled() const;
@@ -1718,8 +1755,8 @@ class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform);
private:
- bool default_value_enabled;
- Transform default_value;
+ bool default_value_enabled = false;
+ Transform default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
protected:
static void _bind_methods();
@@ -1738,6 +1775,9 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
void set_default_value_enabled(bool p_enabled);
bool is_default_value_enabled() const;
@@ -1770,8 +1810,8 @@ public:
};
protected:
- TextureType texture_type;
- ColorDefault color_default;
+ TextureType texture_type = TYPE_DATA;
+ ColorDefault color_default = COLOR_DEFAULT_WHITE;
protected:
static void _bind_methods();
@@ -1855,6 +1895,29 @@ public:
///////////////////////////////////////
+class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform {
+ GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+
+ VisualShaderNodeTexture3DUniform();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform {
GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform);
@@ -1973,7 +2036,7 @@ public:
};
protected:
- Function func;
+ Function func = FUNC_IS_INF;
protected:
static void _bind_methods();
@@ -2032,9 +2095,9 @@ public:
};
protected:
- ComparisonType ctype;
- Function func;
- Condition condition;
+ ComparisonType ctype = CTYPE_SCALAR;
+ Function func = FUNC_EQUAL;
+ Condition condition = COND_ALL;
protected:
static void _bind_methods();
@@ -2082,7 +2145,7 @@ public:
};
protected:
- Type type;
+ Type type = TYPE_SCALAR;
protected:
static void _bind_methods();
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 32d4e9e569..356f4b884a 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -186,10 +186,18 @@ DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
+void DisplayServer::show_window(WindowID p_id) {
+ ERR_FAIL_MSG("Sub-windows not supported by this display server.");
+}
+
void DisplayServer::delete_sub_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}
+void DisplayServer::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
+ ERR_FAIL_MSG("Mouse passthrough not supported by this display server.");
+}
+
void DisplayServer::window_set_ime_active(const bool p_active, WindowID p_window) {
WARN_PRINT("IME not supported by this display server.");
}
@@ -408,6 +416,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window);
ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_set_mouse_passthrough", "region", "window_id"), &DisplayServer::window_set_mouse_passthrough, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_get_current_screen", "window_id"), &DisplayServer::window_get_current_screen, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_current_screen", "screen", "window_id"), &DisplayServer::window_set_current_screen, DEFVAL(MAIN_WINDOW_ID));
diff --git a/servers/display_server.h b/servers/display_server.h
index fc6520fa5e..3ee0da709b 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -220,6 +220,7 @@ public:
};
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+ virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
@@ -246,6 +247,8 @@ public:
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) = 0;
+ virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID);
+
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const = 0;
virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) = 0;
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 856bba78f7..75c9a95739 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -468,7 +468,7 @@ void Body2DSW::integrate_forces(real_t p_step) {
linear_velocity = motion / p_step;
real_t rot = new_transform.get_rotation() - get_transform().get_rotation();
- angular_velocity = rot / p_step;
+ angular_velocity = remainder(rot, 2.0 * Math_PI) / p_step;
do_motion = true;
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 5997959432..2021aab17c 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -478,8 +478,8 @@ void BodyPair2DSW::solve(real_t p_step) {
Vector2 jb = c.normal * (c.acc_bias_impulse - jbnOld);
- A->apply_bias_impulse(c.rA, -jb);
- B->apply_bias_impulse(c.rB, jb);
+ A->apply_bias_impulse(-jb, c.rA);
+ B->apply_bias_impulse(jb, c.rB);
real_t jn = -(c.bounce + vn) * c.mass_normal;
real_t jnOld = c.acc_normal_impulse;
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp
index ffdaab0d92..1b396190e9 100644
--- a/servers/physics_2d/physics_server_2d_sw.cpp
+++ b/servers/physics_2d/physics_server_2d_sw.cpp
@@ -1342,6 +1342,10 @@ PhysicsServer2DSW::PhysicsServer2DSW() {
island_count = 0;
active_objects = 0;
collision_pairs = 0;
+#ifdef NO_THREADS
+ using_threads = false;
+#else
using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2;
+#endif
flushing_queries = false;
};
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h
index bc918b20f4..586dbe9e12 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.h
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.h
@@ -317,6 +317,9 @@ public:
template <class T>
static PhysicsServer2D *init_server() {
+#ifdef NO_THREADS
+ return memnew(T); // Always single unsafe when no threads are available.
+#else
int tm = GLOBAL_DEF("physics/2d/thread_model", 1);
if (tm == 0) { // single unsafe
return memnew(T);
@@ -325,6 +328,7 @@ public:
} else { // multi threaded
return memnew(PhysicsServer2DWrapMT(memnew(T), true));
}
+#endif
}
#undef ServerNameWrapMT
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index e631046524..f609adccf9 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -644,7 +644,7 @@ class PhysicsServer2DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo operator=(const ClassInfo &p_ci) {
+ ClassInfo &operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
return *this;
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index dcb183aea4..b779942460 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -785,7 +785,7 @@ class PhysicsServer3DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo operator=(const ClassInfo &p_ci) {
+ ClassInfo &operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
return *this;
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index e1282fdf71..a24189bdd7 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -86,8 +86,9 @@ public:
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
+ virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
@@ -330,12 +331,12 @@ public:
virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
- virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) = 0;
+ virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
//these two APIs can be used together or in combination with the others.
@@ -345,7 +346,7 @@ public:
virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0;
- virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const = 0;
+ virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0;
virtual void texture_replace(RID p_texture, RID p_by_texture) = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -660,6 +661,8 @@ public:
virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
virtual void particles_restart(RID p_particles) = 0;
+ virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0;
+ virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0;
virtual bool particles_is_inactive(RID p_particles) const = 0;
@@ -677,6 +680,8 @@ public:
virtual int particles_get_draw_passes(RID p_particles) const = 0;
virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
+ virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
+
/* GLOBAL VARIABLES */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
index b3279f041f..527ed09584 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -389,7 +389,7 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture,
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
+void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
@@ -415,12 +415,12 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture,
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
if (p_auto_exposure.is_valid() && p_first_pass) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1);
}
- copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);
+ copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
@@ -430,8 +430,8 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture,
//VERTICAL
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
copy.push_constant.flags = base_flags;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
@@ -1273,6 +1273,76 @@ void RasterizerEffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, cons
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1);
}
}
+
+void RasterizerEffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
+ Sort::PushConstant push_constant;
+ push_constant.total_elements = p_size;
+
+ bool done = true;
+
+ int numThreadGroups = ((p_size - 1) >> 9) + 1;
+
+ if (numThreadGroups > 1) {
+ done = false;
+ }
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_BLOCK]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+
+ int presorted = 512;
+
+ while (!done) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ done = true;
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_STEP]);
+
+ numThreadGroups = 0;
+
+ if (p_size > presorted) {
+ if (p_size > presorted * 2) {
+ done = false;
+ }
+
+ int pow2 = presorted;
+ while (pow2 < p_size) {
+ pow2 *= 2;
+ }
+ numThreadGroups = pow2 >> 9;
+ }
+
+ unsigned int nMergeSize = presorted * 2;
+
+ for (unsigned int nMergeSubSize = nMergeSize >> 1; nMergeSubSize > 256; nMergeSubSize = nMergeSubSize >> 1) {
+ push_constant.job_params[0] = nMergeSubSize;
+ if (nMergeSubSize == nMergeSize >> 1) {
+ push_constant.job_params[1] = (2 * nMergeSubSize - 1);
+ push_constant.job_params[2] = -1;
+ } else {
+ push_constant.job_params[1] = nMergeSubSize;
+ push_constant.job_params[2] = 1;
+ }
+ push_constant.job_params[3] = 0;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_INNER]);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+
+ presorted *= 2;
+ }
+
+ RD::get_singleton()->compute_list_end();
+}
+
RasterizerEffectsRD::RasterizerEffectsRD() {
{ // Initialize copy
Vector<String> copy_modes;
@@ -1618,6 +1688,21 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
}
}
+ {
+ Vector<String> sort_modes;
+ sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
+ sort_modes.push_back("\n#define MODE_SORT_STEP\n");
+ sort_modes.push_back("\n#define MODE_SORT_INNER\n");
+
+ sort.shader.initialize(sort_modes);
+
+ sort.shader_version = sort.shader.version_create();
+
+ for (int i = 0; i < SORT_MODE_MAX; i++) {
+ sort.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sort.shader.version_get_shader(sort.shader_version, i));
+ }
+ }
+
RD::SamplerState sampler;
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
index b0964f23e7..e434bbc372 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
@@ -47,6 +47,7 @@
#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/shadow_reduce.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/sort.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/specular_merge.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/ssao.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl.gen.h"
@@ -81,7 +82,8 @@ class RasterizerEffectsRD {
COPY_FLAG_GLOW_FIRST_PASS = (1 << 4),
COPY_FLAG_FLIP_Y = (1 << 5),
COPY_FLAG_FORCE_LUMINANCE = (1 << 6),
- COPY_FLAG_ALL_SOURCE = (1 << 7)
+ COPY_FLAG_ALL_SOURCE = (1 << 7),
+ COPY_FLAG_HIGH_QUALITY_GLOW = (1 << 8)
};
struct CopyPushConstant {
@@ -544,9 +546,28 @@ class RasterizerEffectsRD {
struct ShadowReduce {
ShadowReduceShaderRD shader;
RID shader_version;
- RID pipelines[2];
+ RID pipelines[SHADOW_REDUCE_MAX];
} shadow_reduce;
+ enum SortMode {
+ SORT_MODE_BLOCK,
+ SORT_MODE_STEP,
+ SORT_MODE_INNER,
+ SORT_MODE_MAX
+ };
+
+ struct Sort {
+ struct PushConstant {
+ uint32_t total_elements;
+ uint32_t pad[3];
+ int32_t job_params[4];
+ };
+
+ SortShaderRD shader;
+ RID shader_version;
+ RID pipelines[SORT_MODE_MAX];
+ } sort;
+
RID default_sampler;
RID default_mipmap_sampler;
RID index_buffer;
@@ -586,7 +607,7 @@ public:
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false);
- void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
+ void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
@@ -649,6 +670,8 @@ public:
void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list);
void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true);
+ void sort_buffer(RID p_uniform_set, int p_size);
+
RasterizerEffectsRD();
~RasterizerEffectsRD();
};
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index 11abb8f4a8..c56c208098 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -782,8 +782,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements,
for (int i = 0; i < p_element_count; i++) {
const RenderList::Element *e = p_elements[i];
InstanceData &id = scene_state.instances[i];
- RasterizerStorageRD::store_transform(e->instance->transform, id.transform);
- RasterizerStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
+ bool store_transform = true;
id.flags = 0;
id.mask = e->instance->layer_mask;
id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0;
@@ -807,12 +806,42 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements,
}
id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+ } else if (e->instance->base_type == RS::INSTANCE_PARTICLES) {
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (false) { // 2D particles
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+
+ id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+
+ id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+
+ if (!storage->particles_is_using_local_coords(e->instance->base)) {
+ store_transform = false;
+ }
+
} else if (e->instance->base_type == RS::INSTANCE_MESH) {
if (e->instance->skeleton.is_valid()) {
id.flags |= INSTANCE_DATA_FLAG_SKELETON;
}
}
+ if (store_transform) {
+ RasterizerStorageRD::store_transform(e->instance->transform, id.transform);
+ RasterizerStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
+ } else {
+ RasterizerStorageRD::store_transform(Transform(), id.transform);
+ RasterizerStorageRD::store_transform(Transform(), id.normal_transform);
+ }
+
if (p_for_depth) {
id.gi_offset = 0xFFFFFFFF;
continue;
@@ -967,7 +996,12 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
ERR_CONTINUE(true); //should be a bug
} break;
case RS::INSTANCE_PARTICLES: {
- ERR_CONTINUE(true); //should be a bug
+ RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16);
+ ERR_CONTINUE(!mesh.is_valid()); //should be a bug
+ primitive = storage->mesh_surface_get_primitive(mesh, e->surface_index & 0xFFFF);
+
+ xforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+
} break;
default: {
ERR_CONTINUE(true); //should be a bug
@@ -1036,7 +1070,9 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
ERR_CONTINUE(true); //should be a bug
} break;
case RS::INSTANCE_PARTICLES: {
- ERR_CONTINUE(true); //should be a bug
+ RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16);
+ ERR_CONTINUE(!mesh.is_valid()); //should be a bug
+ storage->mesh_surface_get_arrays_and_format(mesh, e->surface_index & 0xFFFF, pipeline->get_vertex_input_mask(), vertex_array_rd, index_array_rd, vertex_format);
} break;
default: {
ERR_CONTINUE(true); //should be a bug
@@ -1092,6 +1128,8 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
case RS::INSTANCE_IMMEDIATE: {
} break;
case RS::INSTANCE_PARTICLES: {
+ uint32_t instances = storage->particles_get_amount(e->instance->base);
+ RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
} break;
default: {
ERR_CONTINUE(true); //should be a bug
@@ -1524,31 +1562,31 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
_add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass);
} break;
+#endif
case RS::INSTANCE_PARTICLES: {
+ int draw_passes = storage->particles_get_draw_passes(inst->base);
- RasterizerStorageGLES3::Particles *particles = storage->particles_owner.getornull(inst->base);
- ERR_CONTINUE(!particles);
-
- for (int j = 0; j < particles->draw_passes.size(); j++) {
-
- RID pmesh = particles->draw_passes[j];
- if (!pmesh.is_valid())
+ for (int j = 0; j < draw_passes; j++) {
+ RID mesh = storage->particles_get_draw_pass_mesh(inst->base, j);
+ if (!mesh.is_valid())
continue;
- RasterizerStorageGLES3::Mesh *mesh = storage->mesh_owner.getornull(pmesh);
- if (!mesh)
- continue; //mesh not assigned
- int ssize = mesh->surfaces.size();
+ const RID *materials = nullptr;
+ uint32_t surface_count;
- for (int k = 0; k < ssize; k++) {
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (!materials) {
+ continue; //nothing to do
+ }
- RasterizerStorageGLES3::Surface *s = mesh->surfaces[k];
- _add_geometry(s, inst, particles, -1, p_depth_pass, p_shadow_pass);
+ for (uint32_t k = 0; k < surface_count; k++) {
+ uint32_t surface_index = storage->mesh_surface_get_particles_render_pass_index(mesh, j, render_pass, &geometry_index);
+ _add_geometry(inst, (j << 16) | k, materials[j], p_pass_mode, surface_index, p_using_sdfgi);
}
}
} break;
-#endif
+
default: {
}
}
@@ -2696,6 +2734,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["LIGHT_COLOR"] = "light_color";
actions.renames["LIGHT"] = "light";
actions.renames["ATTENUATION"] = "attenuation";
+ actions.renames["SHADOW_ATTENUATION"] = "shadow_attenuation";
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
actions.renames["SPECULAR_LIGHT"] = "specular_light";
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index 34818d2683..958d8eac1f 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -2951,6 +2951,10 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable)
glow_bicubic_upscale = p_enable;
}
+void RasterizerSceneRD::environment_glow_set_use_high_quality(bool p_enable) {
+ glow_high_quality = p_enable;
+}
+
void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -5265,9 +5269,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (env->auto_exposure && rb->luminance.current.is_valid()) {
luminance_texture = rb->luminance.current;
}
- storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
+ storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
} else {
- storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength);
+ storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality);
}
}
}
@@ -8310,6 +8314,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount");
screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit");
glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
+ glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality");
ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality")));
sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index f504240f50..fe31d2f76b 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -359,7 +359,7 @@ private:
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
- /* REFLECTION PROBE INSTANCE */
+ /* DECAL INSTANCE */
struct DecalInstance {
RID decal;
@@ -765,6 +765,7 @@ private:
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
bool glow_bicubic_upscale = false;
+ bool glow_high_quality = false;
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW;
static uint64_t auto_exposure_counter;
@@ -1530,6 +1531,7 @@ public:
void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
void environment_glow_set_use_bicubic_upscale(bool p_enable);
+ void environment_glow_set_use_high_quality(bool p_enable);
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density);
bool environment_is_fog_enabled(RID p_env) const;
@@ -1540,7 +1542,7 @@ public:
float environment_get_fog_height(RID p_env) const;
float environment_get_fog_height_density(RID p_env) const;
- void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter);
+ void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter);
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
virtual void environment_set_volumetric_fog_filter_active(bool p_enable);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index f3ba57e733..a13e7d786b 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -33,6 +33,7 @@
#include "core/engine.h"
#include "core/io/resource_loader.h"
#include "core/project_settings.h"
+#include "rasterizer_rd.h"
#include "servers/rendering/shader_language.h"
Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
@@ -714,8 +715,120 @@ RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_l
return texture_owner.make_rid(texture);
}
-RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) {
- return RID();
+RID RasterizerStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
+ ERR_FAIL_COND_V(p_data.size() == 0, RID());
+ Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
+ if (verr != Image::VALIDATE_3D_OK) {
+ ERR_FAIL_V_MSG(RID(), Image::get_3d_image_validation_error_text(verr));
+ }
+
+ TextureToRDFormat ret_format;
+ Image::Format validated_format = Image::FORMAT_MAX;
+ Vector<uint8_t> all_data;
+ uint32_t mipmap_count = 0;
+ Vector<Texture::BufferSlice3D> slices;
+ {
+ Vector<Ref<Image>> images;
+ uint32_t all_data_size = 0;
+ images.resize(p_data.size());
+ for (int i = 0; i < p_data.size(); i++) {
+ TextureToRDFormat f;
+ images.write[i] = _validate_texture_format(p_data[i], f);
+ if (i == 0) {
+ ret_format = f;
+ validated_format = images[0]->get_format();
+ }
+
+ all_data_size += images[i]->get_data().size();
+ }
+
+ all_data.resize(all_data_size); //consolidate all data here
+ uint32_t offset = 0;
+ Size2i prev_size;
+ for (int i = 0; i < p_data.size(); i++) {
+ uint32_t s = images[i]->get_data().size();
+
+ copymem(&all_data.write[offset], images[i]->get_data().ptr(), s);
+ {
+ Texture::BufferSlice3D slice;
+ slice.size.width = images[i]->get_width();
+ slice.size.height = images[i]->get_height();
+ slice.offset = offset;
+ slice.buffer_size = s;
+ slices.push_back(slice);
+ }
+ offset += s;
+
+ Size2i img_size(images[i]->get_width(), images[i]->get_height());
+ if (img_size != prev_size) {
+ mipmap_count++;
+ }
+ prev_size = img_size;
+ }
+ }
+
+ Texture texture;
+
+ texture.type = Texture::TYPE_3D;
+ texture.width = p_width;
+ texture.height = p_height;
+ texture.depth = p_depth;
+ texture.mipmaps = mipmap_count;
+ texture.format = p_data[0]->get_format();
+ texture.validated_format = validated_format;
+
+ texture.buffer_size_3d = all_data.size();
+ texture.buffer_slices_3d = slices;
+
+ texture.rd_type = RD::TEXTURE_TYPE_3D;
+ texture.rd_format = ret_format.format;
+ texture.rd_format_srgb = ret_format.format_srgb;
+
+ RD::TextureFormat rd_format;
+ RD::TextureView rd_view;
+ { //attempt register
+ rd_format.format = texture.rd_format;
+ rd_format.width = texture.width;
+ rd_format.height = texture.height;
+ rd_format.depth = texture.depth;
+ rd_format.array_layers = 1;
+ rd_format.mipmaps = texture.mipmaps;
+ rd_format.type = texture.rd_type;
+ rd_format.samples = RD::TEXTURE_SAMPLES_1;
+ rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
+ rd_format.shareable_formats.push_back(texture.rd_format);
+ rd_format.shareable_formats.push_back(texture.rd_format_srgb);
+ }
+ }
+ {
+ rd_view.swizzle_r = ret_format.swizzle_r;
+ rd_view.swizzle_g = ret_format.swizzle_g;
+ rd_view.swizzle_b = ret_format.swizzle_b;
+ rd_view.swizzle_a = ret_format.swizzle_a;
+ }
+ Vector<Vector<uint8_t>> data_slices;
+ data_slices.push_back(all_data); //one slice
+
+ texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
+ ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID());
+ if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
+ rd_view.format_override = texture.rd_format_srgb;
+ texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
+ if (texture.rd_texture_srgb.is_null()) {
+ RD::get_singleton()->free(texture.rd_texture);
+ ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID());
+ }
+ }
+
+ //used for 2D, overridable
+ texture.width_2d = texture.width;
+ texture.height_2d = texture.height;
+ texture.is_render_target = false;
+ texture.rd_view = rd_view;
+ texture.is_proxy = false;
+
+ return texture_owner.make_rid(texture);
}
RID RasterizerStorageRD::texture_proxy_create(RID p_base) {
@@ -771,7 +884,41 @@ void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_i
_texture_2d_update(p_texture, p_image, p_layer, false);
}
-void RasterizerStorageRD::texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) {
+void RasterizerStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!tex);
+ ERR_FAIL_COND(tex->type != Texture::TYPE_3D);
+ Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data);
+ if (verr != Image::VALIDATE_3D_OK) {
+ ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr));
+ }
+
+ Vector<uint8_t> all_data;
+ {
+ Vector<Ref<Image>> images;
+ uint32_t all_data_size = 0;
+ images.resize(p_data.size());
+ for (int i = 0; i < p_data.size(); i++) {
+ Ref<Image> image = p_data[i];
+ if (image->get_format() != tex->validated_format) {
+ image = image->duplicate();
+ image->convert(tex->validated_format);
+ }
+ all_data_size += images[i]->get_data().size();
+ images.push_back(image);
+ }
+
+ all_data.resize(all_data_size); //consolidate all data here
+ uint32_t offset = 0;
+
+ for (int i = 0; i < p_data.size(); i++) {
+ uint32_t s = images[i]->get_data().size();
+ copymem(&all_data.write[offset], images[i]->get_data().ptr(), s);
+ offset += s;
+ }
+ }
+
+ RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true);
}
void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
@@ -857,7 +1004,25 @@ RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayere
}
RID RasterizerStorageRD::texture_3d_placeholder_create() {
- return RID();
+ //this could be better optimized to reuse an existing image , done this way
+ //for now to get it working
+ Ref<Image> image;
+ image.instance();
+ image->create(4, 4, false, Image::FORMAT_RGBA8);
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ image->set_pixel(i, j, Color(1, 0, 1, 1));
+ }
+ }
+
+ Vector<Ref<Image>> images;
+ //cube
+ for (int i = 0; i < 4; i++) {
+ images.push_back(image);
+ }
+
+ return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images);
}
Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
@@ -889,11 +1054,51 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
}
Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const {
- return Ref<Image>();
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND_V(!tex, Ref<Image>());
+
+ Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer);
+ ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
+ Ref<Image> image;
+ image.instance();
+ image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
+ ERR_FAIL_COND_V(image->empty(), Ref<Image>());
+ if (tex->format != tex->validated_format) {
+ image->convert(tex->format);
+ }
+
+ return image;
}
-Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const {
- return Ref<Image>();
+Vector<Ref<Image>> RasterizerStorageRD::texture_3d_get(RID p_texture) const {
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>());
+ ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>());
+
+ Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
+
+ ERR_FAIL_COND_V(all_data.size() != (int)tex->buffer_size_3d, Vector<Ref<Image>>());
+
+ Vector<Ref<Image>> ret;
+
+ for (int i = 0; i < tex->buffer_slices_3d.size(); i++) {
+ const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i];
+ ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>());
+ ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>());
+ Vector<uint8_t> sub_region = all_data.subarray(bs.offset, bs.offset + bs.buffer_size - 1);
+
+ Ref<Image> img;
+ img.instance();
+ img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region);
+ ERR_FAIL_COND_V(img->empty(), Vector<Ref<Image>>());
+ if (tex->format != tex->validated_format) {
+ img->convert(tex->format);
+ }
+
+ ret.push_back(img);
+ }
+
+ return ret;
}
void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
@@ -3003,9 +3208,9 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const {
Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
Vector<float> ret;
- ret.resize(multimesh->instances);
+ ret.resize(multimesh->instances * multimesh->stride_cache);
{
- float *w = multimesh->data_cache.ptrw();
+ float *w = ret.ptrw();
const uint8_t *r = buffer.ptr();
copymem(w, r, buffer.size());
}
@@ -3098,8 +3303,914 @@ void RasterizerStorageRD::_update_dirty_multimeshes() {
multimesh_dirty_list = nullptr;
}
-/* SKELETON */
+/* PARTICLES */
+
+RID RasterizerStorageRD::particles_create() {
+ return particles_owner.make_rid(Particles());
+}
+
+void RasterizerStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->emitting = p_emitting;
+}
+
+bool RasterizerStorageRD::particles_get_emitting(RID p_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, false);
+
+ return particles->emitting;
+}
+
+void RasterizerStorageRD::_particles_free_data(Particles *particles) {
+ if (!particles->particle_buffer.is_valid()) {
+ return;
+ }
+ RD::get_singleton()->free(particles->particle_buffer);
+ RD::get_singleton()->free(particles->frame_params_buffer);
+ RD::get_singleton()->free(particles->particle_instance_buffer);
+ particles->particles_transforms_buffer_uniform_set = RID();
+ particles->particle_buffer = RID();
+
+ if (particles->particles_sort_buffer.is_valid()) {
+ RD::get_singleton()->free(particles->particles_sort_buffer);
+ particles->particles_sort_buffer = RID();
+ }
+
+ if (particles->emission_buffer != nullptr) {
+ particles->emission_buffer = nullptr;
+ particles->emission_buffer_data.clear();
+ RD::get_singleton()->free(particles->emission_storage_buffer);
+ particles->emission_storage_buffer = RID();
+ }
+}
+
+void RasterizerStorageRD::particles_set_amount(RID p_particles, int p_amount) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ if (particles->amount == p_amount) {
+ return;
+ }
+
+ _particles_free_data(particles);
+
+ particles->amount = p_amount;
+
+ if (particles->amount > 0) {
+ particles->particle_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticleData) * p_amount);
+ particles->frame_params_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticlesFrameParams) * 1);
+ particles->particle_instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * 4 * (3 + 1 + 1) * p_amount);
+ //needs to clear it
+
+ {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(particles->particle_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(particles->particle_instance_buffer);
+ uniforms.push_back(u);
+ }
+
+ particles->particles_copy_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.copy_shader.version_get_shader(particles_shader.copy_shader_version, 0), 0);
+ }
+ }
+
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+}
+
+void RasterizerStorageRD::particles_set_lifetime(RID p_particles, float p_lifetime) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->lifetime = p_lifetime;
+}
+
+void RasterizerStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->one_shot = p_one_shot;
+}
+
+void RasterizerStorageRD::particles_set_pre_process_time(RID p_particles, float p_time) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->pre_process_time = p_time;
+}
+void RasterizerStorageRD::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->explosiveness = p_ratio;
+}
+void RasterizerStorageRD::particles_set_randomness_ratio(RID p_particles, float p_ratio) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->randomness = p_ratio;
+}
+
+void RasterizerStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ particles->custom_aabb = p_aabb;
+ particles->instance_dependency.instance_notify_changed(true, false);
+}
+
+void RasterizerStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->speed_scale = p_scale;
+}
+void RasterizerStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->use_local_coords = p_enable;
+}
+
+void RasterizerStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->fixed_fps = p_fps;
+}
+
+void RasterizerStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->fractional_delta = p_enable;
+}
+
+void RasterizerStorageRD::particles_set_process_material(RID p_particles, RID p_material) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->process_material = p_material;
+}
+
+void RasterizerStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->draw_order = p_order;
+}
+
+void RasterizerStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->draw_passes.resize(p_passes);
+}
+
+void RasterizerStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
+ particles->draw_passes.write[p_pass] = p_mesh;
+}
+
+void RasterizerStorageRD::particles_restart(RID p_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->restart_request = true;
+}
+
+void RasterizerStorageRD::_particles_allocate_emission_buffer(Particles *particles) {
+ ERR_FAIL_COND(particles->emission_buffer != nullptr);
+
+ particles->emission_buffer_data.resize(sizeof(ParticleEmissionBuffer::Data) * particles->amount + sizeof(uint32_t) * 4);
+ zeromem(particles->emission_buffer_data.ptrw(), particles->emission_buffer_data.size());
+ particles->emission_buffer = (ParticleEmissionBuffer *)particles->emission_buffer_data.ptrw();
+ particles->emission_buffer->particle_max = particles->amount;
+
+ particles->emission_storage_buffer = RD::get_singleton()->storage_buffer_create(particles->emission_buffer_data.size(), particles->emission_buffer_data);
+
+ if (RD::get_singleton()->uniform_set_is_valid(particles->particles_material_uniform_set)) {
+ //will need to be re-created
+ RD::get_singleton()->free(particles->particles_material_uniform_set);
+ particles->particles_material_uniform_set = RID();
+ }
+}
+
+void RasterizerStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ ERR_FAIL_COND(p_particles == p_subemitter_particles);
+
+ particles->sub_emitter = p_subemitter_particles;
+
+ if (RD::get_singleton()->uniform_set_is_valid(particles->particles_material_uniform_set)) {
+ RD::get_singleton()->free(particles->particles_material_uniform_set);
+ particles->particles_material_uniform_set = RID(); //clear and force to re create sub emitting
+ }
+}
+
+void RasterizerStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+ ERR_FAIL_COND(particles->amount == 0);
+
+ if (particles->emitting) {
+ particles->clear = true;
+ particles->emitting = false;
+ }
+
+ if (particles->emission_buffer == nullptr) {
+ _particles_allocate_emission_buffer(particles);
+ }
+
+ if (particles->inactive) {
+ //in case it was inactive, make active again
+ particles->inactive = false;
+ particles->inactive_time = 0;
+ }
+
+ int32_t idx = particles->emission_buffer->particle_count;
+ if (idx < particles->emission_buffer->particle_max) {
+ store_transform(p_transform, particles->emission_buffer->data[idx].xform);
+
+ particles->emission_buffer->data[idx].velocity[0] = p_velocity.x;
+ particles->emission_buffer->data[idx].velocity[1] = p_velocity.y;
+ particles->emission_buffer->data[idx].velocity[2] = p_velocity.z;
+
+ particles->emission_buffer->data[idx].custom[0] = p_custom.r;
+ particles->emission_buffer->data[idx].custom[1] = p_custom.g;
+ particles->emission_buffer->data[idx].custom[2] = p_custom.b;
+ particles->emission_buffer->data[idx].custom[3] = p_custom.a;
+
+ particles->emission_buffer->data[idx].color[0] = p_color.r;
+ particles->emission_buffer->data[idx].color[1] = p_color.g;
+ particles->emission_buffer->data[idx].color[2] = p_color.b;
+ particles->emission_buffer->data[idx].color[3] = p_color.a;
+
+ particles->emission_buffer->data[idx].flags = p_emit_flags;
+ particles->emission_buffer->particle_count++;
+ }
+}
+
+void RasterizerStorageRD::particles_request_process(RID p_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ if (!particles->dirty) {
+ particles->dirty = true;
+ particles->update_list = particle_update_list;
+ particle_update_list = particles;
+ }
+}
+
+AABB RasterizerStorageRD::particles_get_current_aabb(RID p_particles) {
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, AABB());
+
+ Vector<ParticleData> data;
+ data.resize(particles->amount);
+
+ Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(particles->particle_buffer);
+
+ Transform inv = particles->emission_transform.affine_inverse();
+
+ AABB aabb;
+ if (buffer.size()) {
+ bool first = true;
+ const ParticleData *particle_data = (const ParticleData *)data.ptr();
+ for (int i = 0; i < particles->amount; i++) {
+ if (particle_data[i].active) {
+ Vector3 pos = Vector3(particle_data[i].xform[12], particle_data[i].xform[13], particle_data[i].xform[14]);
+ if (!particles->use_local_coords) {
+ pos = inv.xform(pos);
+ }
+ if (first) {
+ aabb.position = pos;
+ first = false;
+ } else {
+ aabb.expand_to(pos);
+ }
+ }
+ }
+ }
+
+ float longest_axis_size = 0;
+ for (int i = 0; i < particles->draw_passes.size(); i++) {
+ if (particles->draw_passes[i].is_valid()) {
+ AABB maabb = mesh_get_aabb(particles->draw_passes[i], RID());
+ longest_axis_size = MAX(maabb.get_longest_axis_size(), longest_axis_size);
+ }
+ }
+
+ aabb.grow_by(longest_axis_size);
+
+ return aabb;
+}
+
+AABB RasterizerStorageRD::particles_get_aabb(RID p_particles) const {
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, AABB());
+
+ return particles->custom_aabb;
+}
+
+void RasterizerStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ particles->emission_transform = p_transform;
+}
+
+int RasterizerStorageRD::particles_get_draw_passes(RID p_particles) const {
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, 0);
+
+ return particles->draw_passes.size();
+}
+
+RID RasterizerStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, RID());
+ ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
+ return particles->draw_passes[p_pass];
+}
+
+void RasterizerStorageRD::_particles_process(Particles *p_particles, float p_delta) {
+ if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(p_particles->frame_params_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(p_particles->particle_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ if (p_particles->emission_storage_buffer.is_valid()) {
+ u.ids.push_back(p_particles->emission_storage_buffer);
+ } else {
+ u.ids.push_back(default_rd_storage_buffer);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 3;
+ Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter);
+ if (sub_emitter) {
+ if (sub_emitter->emission_buffer == nullptr) { //no emission buffer, allocate emission buffer
+ _particles_allocate_emission_buffer(sub_emitter);
+ }
+ u.ids.push_back(sub_emitter->emission_storage_buffer);
+ } else {
+ u.ids.push_back(default_rd_storage_buffer);
+ }
+ uniforms.push_back(u);
+ }
+
+ p_particles->particles_material_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 1);
+ }
+
+ float new_phase = Math::fmod((float)p_particles->phase + (p_delta / p_particles->lifetime) * p_particles->speed_scale, (float)1.0);
+
+ ParticlesFrameParams &frame_params = p_particles->frame_params;
+
+ if (p_particles->clear) {
+ p_particles->cycle_number = 0;
+ p_particles->random_seed = Math::rand();
+ } else if (new_phase < p_particles->phase) {
+ if (p_particles->one_shot) {
+ p_particles->emitting = false;
+ }
+ p_particles->cycle_number++;
+ }
+
+ frame_params.emitting = p_particles->emitting;
+ frame_params.system_phase = new_phase;
+ frame_params.prev_system_phase = p_particles->phase;
+
+ p_particles->phase = new_phase;
+
+ frame_params.time = RasterizerRD::singleton->get_total_time();
+ frame_params.delta = p_delta * p_particles->speed_scale;
+ frame_params.random_seed = p_particles->random_seed;
+ frame_params.explosiveness = p_particles->explosiveness;
+ frame_params.randomness = p_particles->randomness;
+
+ if (p_particles->use_local_coords) {
+ store_transform(Transform(), frame_params.emission_transform);
+ } else {
+ store_transform(p_particles->emission_transform, frame_params.emission_transform);
+ }
+
+ frame_params.cycle = p_particles->cycle_number;
+
+ ParticlesShader::PushConstant push_constant;
+
+ push_constant.clear = p_particles->clear;
+ push_constant.total_particles = p_particles->amount;
+ push_constant.lifetime = p_particles->lifetime;
+ push_constant.trail_size = 1;
+ push_constant.use_fractional_delta = p_particles->fractional_delta;
+ push_constant.sub_emitter_mode = !p_particles->emitting && p_particles->emission_buffer && (p_particles->emission_buffer->particle_count > 0 || p_particles->force_sub_emit);
+
+ p_particles->force_sub_emit = false; //reset
+
+ Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter);
+
+ if (sub_emitter && sub_emitter->emission_storage_buffer.is_valid()) {
+ // print_line("updating subemitter buffer");
+ int32_t zero[4] = { 0, sub_emitter->amount, 0, 0 };
+ RD::get_singleton()->buffer_update(sub_emitter->emission_storage_buffer, 0, sizeof(uint32_t) * 4, zero, true);
+ push_constant.can_emit = true;
+
+ if (sub_emitter->emitting) {
+ sub_emitter->emitting = false;
+ sub_emitter->clear = true; //will need to clear if it was emitting, sorry
+ }
+ //make sure the sub emitter processes particles too
+ sub_emitter->inactive = false;
+ sub_emitter->inactive_time = 0;
+
+ sub_emitter->force_sub_emit = true;
+
+ } else {
+ push_constant.can_emit = false;
+ }
+
+ if (p_particles->emission_buffer && p_particles->emission_buffer->particle_count) {
+ RD::get_singleton()->buffer_update(p_particles->emission_storage_buffer, 0, sizeof(uint32_t) * 4 + sizeof(ParticleEmissionBuffer::Data) * p_particles->emission_buffer->particle_count, p_particles->emission_buffer, true);
+ p_particles->emission_buffer->particle_count = 0;
+ }
+
+ p_particles->clear = false;
+
+ RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams), &frame_params, true);
+
+ ParticlesMaterialData *m = (ParticlesMaterialData *)material_get_data(p_particles->process_material, SHADER_TYPE_PARTICLES);
+ if (!m) {
+ m = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, SHADER_TYPE_PARTICLES);
+ }
+
+ ERR_FAIL_COND(!m);
+
+ //todo should maybe compute all particle systems together?
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, m->shader_data->pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles_shader.base_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_particles->particles_material_uniform_set, 1);
+ if (m->uniform_set.is_valid()) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, m->uniform_set, 2);
+ }
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1, 64, 1, 1);
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void RasterizerStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND(!particles);
+
+ if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH) {
+ return; //uninteresting for other modes
+ }
+
+ //copy to sort buffer
+ if (particles->particles_sort_buffer == RID()) {
+ uint32_t size = particles->amount;
+ if (size & 1) {
+ size++; //make multiple of 16
+ }
+ size *= sizeof(float) * 2;
+ particles->particles_sort_buffer = RD::get_singleton()->storage_buffer_create(size);
+ {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(particles->particles_sort_buffer);
+ uniforms.push_back(u);
+ }
+
+ particles->particles_sort_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.copy_shader.version_get_shader(particles_shader.copy_shader_version, ParticlesShader::COPY_MODE_FILL_SORT_BUFFER), 1);
+ }
+ }
+
+ Vector3 axis = -p_axis; // cameras look to z negative
+
+ if (particles->use_local_coords) {
+ axis = particles->emission_transform.basis.xform_inv(axis).normalized();
+ }
+
+ ParticlesShader::CopyPushConstant copy_push_constant;
+ copy_push_constant.total_particles = particles->amount;
+ copy_push_constant.sort_direction[0] = axis.x;
+ copy_push_constant.sort_direction[1] = axis.y;
+ copy_push_constant.sort_direction[2] = axis.z;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_SORT_BUFFER]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+
+ RD::get_singleton()->compute_list_end();
+
+ effects.sort_buffer(particles->particles_sort_uniform_set, particles->amount);
+
+ compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void RasterizerStorageRD::update_particles() {
+ while (particle_update_list) {
+ //use transform feedback to process particles
+
+ Particles *particles = particle_update_list;
+
+ //take and remove
+ particle_update_list = particles->update_list;
+ particles->update_list = nullptr;
+ particles->dirty = false;
+
+ if (particles->restart_request) {
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+ particles->restart_request = false;
+ }
+
+ if (particles->inactive && !particles->emitting) {
+ //go next
+ continue;
+ }
+
+ if (particles->emitting) {
+ if (particles->inactive) {
+ //restart system from scratch
+ particles->prev_ticks = 0;
+ particles->phase = 0;
+ particles->prev_phase = 0;
+ particles->clear = true;
+ }
+ particles->inactive = false;
+ particles->inactive_time = 0;
+ } else {
+ particles->inactive_time += particles->speed_scale * RasterizerRD::singleton->get_frame_delta_time();
+ if (particles->inactive_time > particles->lifetime * 1.2) {
+ particles->inactive = true;
+ continue;
+ }
+ }
+
+ bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0;
+
+ if (particles->clear && particles->pre_process_time > 0.0) {
+ float frame_time;
+ if (particles->fixed_fps > 0)
+ frame_time = 1.0 / particles->fixed_fps;
+ else
+ frame_time = 1.0 / 30.0;
+
+ float todo = particles->pre_process_time;
+
+ while (todo >= 0) {
+ _particles_process(particles, frame_time);
+ todo -= frame_time;
+ }
+ }
+
+ if (particles->fixed_fps > 0) {
+ float frame_time;
+ float decr;
+ if (zero_time_scale) {
+ frame_time = 0.0;
+ decr = 1.0 / particles->fixed_fps;
+ } else {
+ frame_time = 1.0 / particles->fixed_fps;
+ decr = frame_time;
+ }
+ float delta = RasterizerRD::singleton->get_frame_delta_time();
+ if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
+ delta = 0.1;
+ } else if (delta <= 0.0) { //unlikely but..
+ delta = 0.001;
+ }
+ float todo = particles->frame_remainder + delta;
+
+ while (todo >= frame_time) {
+ _particles_process(particles, frame_time);
+ todo -= decr;
+ }
+
+ particles->frame_remainder = todo;
+
+ } else {
+ if (zero_time_scale)
+ _particles_process(particles, 0.0);
+ else
+ _particles_process(particles, RasterizerRD::singleton->get_frame_delta_time());
+ }
+
+ //copy particles to instance buffer
+
+ if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH) {
+ ParticlesShader::CopyPushConstant copy_push_constant;
+ copy_push_constant.total_particles = particles->amount;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_INSTANCES]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+
+ RD::get_singleton()->compute_list_end();
+ }
+
+ particles->instance_dependency.instance_notify_changed(true, false); //make sure shadows are updated
+ }
+}
+
+bool RasterizerStorageRD::particles_is_inactive(RID p_particles) const {
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, false);
+ return !particles->emitting && particles->inactive;
+}
+
+/* SKY SHADER */
+
+void RasterizerStorageRD::ParticlesShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+
+ if (code == String()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompilerRD::IdentifierActions actions;
+
+ /*
+ uses_time = false;
+
+ actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
+ actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
+
+ actions.usage_flag_pointers["TIME"] = &uses_time;
+*/
+
+ actions.uniforms = &uniforms;
+
+ Error err = base_singleton->particles_shader.compiler.compile(RS::SHADER_PARTICLES, code, &actions, path, gen_code);
+
+ ERR_FAIL_COND(err != OK);
+
+ if (version.is_null()) {
+ version = base_singleton->particles_shader.shader.version_create();
+ }
+
+ base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.uniforms, gen_code.compute_global, gen_code.compute, gen_code.defines);
+ ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version));
+
+ ubo_size = gen_code.uniform_total_size;
+ ubo_offsets = gen_code.uniform_offsets;
+ texture_uniforms = gen_code.texture_uniforms;
+
+ //update pipelines
+
+ pipeline = RD::get_singleton()->compute_pipeline_create(base_singleton->particles_shader.shader.version_get_shader(version, 0));
+
+ valid = true;
+}
+
+void RasterizerStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+ if (!p_texture.is_valid()) {
+ default_texture_params.erase(p_name);
+ } else {
+ default_texture_params[p_name] = p_texture;
+ }
+}
+
+void RasterizerStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+ Map<int, StringName> order;
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
+ }
+
+ for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
+ pi.name = E->get();
+ p_param_list->push_back(pi);
+ }
+}
+
+void RasterizerStorageRD::ParticlesShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RasterizerStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
+bool RasterizerStorageRD::ParticlesShaderData::is_param_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool RasterizerStorageRD::ParticlesShaderData::is_animated() const {
+ return false;
+}
+
+bool RasterizerStorageRD::ParticlesShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant RasterizerStorageRD::ParticlesShaderData::get_default_parameter(const StringName &p_parameter) const {
+ if (uniforms.has(p_parameter)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
+ }
+ return Variant();
+}
+
+RasterizerStorageRD::ParticlesShaderData::ParticlesShaderData() {
+ valid = false;
+}
+
+RasterizerStorageRD::ParticlesShaderData::~ParticlesShaderData() {
+ //pipeline variants will clear themselves if shader is gone
+ if (version.is_valid()) {
+ base_singleton->particles_shader.shader.version_free(version);
+ }
+}
+
+RasterizerStorageRD::ShaderData *RasterizerStorageRD::_create_particles_shader_func() {
+ ParticlesShaderData *shader_data = memnew(ParticlesShaderData);
+ return shader_data;
+}
+
+void RasterizerStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ uniform_set_updated = true;
+
+ if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(shader_data->ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+ update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
+ }
+
+ uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ if (shader_data->ubo_size) {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 2);
+}
+
+RasterizerStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ }
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
+}
+
+RasterizerStorageRD::MaterialData *RasterizerStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
+ ParticlesMaterialData *material_data = memnew(ParticlesMaterialData);
+ material_data->shader_data = p_shader;
+ material_data->last_frame = false;
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+////////
/* SKELETON API */
RID RasterizerStorageRD::skeleton_create() {
@@ -4683,6 +5794,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
} else if (light_owner.owns(p_base)) {
Light *l = light_owner.getornull(p_base);
p_instance->update_dependency(&l->instance_dependency);
+ } else if (particles_owner.owns(p_base)) {
+ Particles *p = particles_owner.getornull(p_base);
+ p_instance->update_dependency(&p->instance_dependency);
}
}
@@ -4715,6 +5829,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
if (lightmap_owner.owns(p_rid)) {
return RS::INSTANCE_LIGHTMAP;
}
+ if (particles_owner.owns(p_rid)) {
+ return RS::INSTANCE_PARTICLES;
+ }
return RS::INSTANCE_NONE;
}
@@ -5618,6 +6735,8 @@ void RasterizerStorageRD::update_dirty_resources() {
_update_dirty_multimeshes();
_update_dirty_skeletons();
_update_decal_atlas();
+
+ update_particles();
}
bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
@@ -5747,6 +6866,11 @@ bool RasterizerStorageRD::free(RID p_rid) {
light->instance_dependency.instance_notify_deleted(p_rid);
light_owner.free(p_rid);
+ } else if (particles_owner.owns(p_rid)) {
+ Particles *particles = particles_owner.getornull(p_rid);
+ _particles_free_data(particles);
+ particles->instance_dependency.instance_notify_deleted(p_rid);
+ particles_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);
@@ -6066,15 +7190,18 @@ RasterizerStorageRD::RasterizerStorageRD() {
case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
} break;
case RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_REPEAT;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_REPEAT;
} break;
case RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: {
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
+ sampler_state.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT;
} break;
default: {
}
@@ -6211,6 +7338,125 @@ RasterizerStorageRD::RasterizerStorageRD() {
}
lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed");
+
+ /* Particles */
+
+ {
+ // Initialize particles
+ Vector<String> particles_modes;
+ particles_modes.push_back("");
+ particles_shader.shader.initialize(particles_modes, String());
+ }
+ shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_shader_funcs);
+ material_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs);
+
+ {
+ ShaderCompilerRD::DefaultIdentifierActions actions;
+
+ actions.renames["COLOR"] = "PARTICLE.color";
+ actions.renames["VELOCITY"] = "PARTICLE.velocity";
+ //actions.renames["MASS"] = "mass"; ?
+ actions.renames["ACTIVE"] = "PARTICLE.is_active";
+ actions.renames["RESTART"] = "restart";
+ actions.renames["CUSTOM"] = "PARTICLE.custom";
+ actions.renames["TRANSFORM"] = "PARTICLE.xform";
+ actions.renames["TIME"] = "FRAME.time";
+ actions.renames["LIFETIME"] = "params.lifetime";
+ actions.renames["DELTA"] = "local_delta";
+ actions.renames["NUMBER"] = "particle";
+ actions.renames["INDEX"] = "index";
+ //actions.renames["GRAVITY"] = "current_gravity";
+ actions.renames["EMISSION_TRANSFORM"] = "FRAME.emission_transform";
+ actions.renames["RANDOM_SEED"] = "FRAME.random_seed";
+ actions.renames["FLAG_EMIT_POSITION"] = "EMISSION_FLAG_HAS_POSITION";
+ actions.renames["FLAG_EMIT_ROT_SCALE"] = "EMISSION_FLAG_HAS_ROTATION_SCALE";
+ actions.renames["FLAG_EMIT_VELOCITY"] = "EMISSION_FLAG_HAS_VELOCITY";
+ actions.renames["FLAG_EMIT_COLOR"] = "EMISSION_FLAG_HAS_COLOR";
+ actions.renames["FLAG_EMIT_CUSTOM"] = "EMISSION_FLAG_HAS_CUSTOM";
+ actions.renames["RESTART_POSITION"] = "restart_position";
+ actions.renames["RESTART_ROT_SCALE"] = "restart_rotation_scale";
+ actions.renames["RESTART_VELOCITY"] = "restart_velocity";
+ actions.renames["RESTART_COLOR"] = "restart_color";
+ actions.renames["RESTART_CUSTOM"] = "restart_custom";
+ actions.renames["emit_particle"] = "emit_particle";
+
+ actions.render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n";
+ actions.render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n";
+ actions.render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n";
+
+ actions.sampler_array_name = "material_samplers";
+ actions.base_texture_binding_index = 1;
+ actions.texture_layout_set = 2;
+ actions.base_uniform_string = "material.";
+ actions.base_varying_index = 10;
+
+ actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
+ actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_variables.data";
+
+ particles_shader.compiler.initialize(actions);
+ }
+
+ {
+ // default material and shader for particles shader
+ particles_shader.default_shader = shader_create();
+ shader_set_code(particles_shader.default_shader, "shader_type particles; void compute() { COLOR = vec4(1.0); } \n");
+ particles_shader.default_material = material_create();
+ material_set_shader(particles_shader.default_material, particles_shader.default_shader);
+
+ ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RasterizerStorageRD::SHADER_TYPE_PARTICLES);
+ particles_shader.default_shader_rd = particles_shader.shader.version_get_shader(md->shader_data->version, 0);
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 1;
+ u.ids.resize(12);
+ RID *ids_ptr = u.ids.ptrw();
+ ids_ptr[0] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[1] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[2] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[3] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[4] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[5] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[6] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[7] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[8] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[9] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[10] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[11] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
+ particles_shader.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, particles_shader.default_shader_rd, 0);
+ }
+
+ default_rd_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4);
+
+ {
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n");
+ copy_modes.push_back("\n#define MODE_FILL_SORT_BUFFER\n#define USE_SORT_BUFFER\n");
+ copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USE_SORT_BUFFER\n");
+
+ particles_shader.copy_shader.initialize(copy_modes);
+
+ particles_shader.copy_shader_version = particles_shader.copy_shader.version_create();
+
+ for (int i = 0; i < ParticlesShader::COPY_MODE_MAX; i++) {
+ particles_shader.copy_pipelines[i] = RD::get_singleton()->compute_pipeline_create(particles_shader.copy_shader.version_get_shader(particles_shader.copy_shader_version, i));
+ }
+ }
}
RasterizerStorageRD::~RasterizerStorageRD() {
@@ -6237,6 +7483,8 @@ RasterizerStorageRD::~RasterizerStorageRD() {
}
giprobe_sdf_shader.version_free(giprobe_sdf_shader_version);
+ RD::get_singleton()->free(default_rd_storage_buffer);
+
if (decal_atlas.textures.size()) {
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index 6e5923953b..e14b9528cf 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -36,6 +36,8 @@
#include "servers/rendering/rasterizer_rd/rasterizer_effects_rd.h"
#include "servers/rendering/rasterizer_rd/shader_compiler_rd.h"
#include "servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/particles.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/particles_copy.glsl.gen.h"
#include "servers/rendering/rendering_device.h"
class RasterizerStorageRD : public RasterizerStorage {
@@ -203,6 +205,14 @@ private:
int height_2d;
int width_2d;
+ struct BufferSlice3D {
+ Size2i size;
+ uint32_t offset = 0;
+ uint32_t buffer_size = 0;
+ };
+ Vector<BufferSlice3D> buffer_slices_3d;
+ uint32_t buffer_size_3d = 0;
+
bool is_render_target;
bool is_proxy;
@@ -247,6 +257,7 @@ private:
RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX];
RID default_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
+ RID default_rd_storage_buffer;
/* DECAL ATLAS */
@@ -386,6 +397,9 @@ private:
uint32_t multimesh_render_index = 0;
uint64_t multimesh_render_pass = 0;
+
+ uint32_t particles_render_index = 0;
+ uint64_t particles_render_pass = 0;
};
uint32_t blend_shape_count = 0;
@@ -448,6 +462,248 @@ private:
_FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
void _update_dirty_multimeshes();
+ /* PARTICLES */
+
+ struct ParticleData {
+ float xform[16];
+ float velocity[3];
+ uint32_t active;
+ float color[4];
+ float custom[3];
+ float lifetime;
+ uint32_t pad[3];
+ };
+
+ struct ParticlesFrameParams {
+ uint32_t emitting;
+ float system_phase;
+ float prev_system_phase;
+ uint32_t cycle;
+
+ float explosiveness;
+ float randomness;
+ float time;
+ float delta;
+
+ uint32_t random_seed;
+ uint32_t pad[3];
+
+ float emission_transform[16];
+ };
+
+ struct ParticleEmissionBufferData {
+ };
+
+ struct ParticleEmissionBuffer {
+ struct Data {
+ float xform[16];
+ float velocity[3];
+ uint32_t flags;
+ float color[4];
+ float custom[4];
+ };
+
+ int32_t particle_count;
+ int32_t particle_max;
+ uint32_t pad1;
+ uint32_t pad2;
+ Data data[1]; //its 2020 and empty arrays are still non standard in C++
+ };
+
+ struct Particles {
+ bool inactive;
+ float inactive_time;
+ bool emitting;
+ bool one_shot;
+ int amount;
+ float lifetime;
+ float pre_process_time;
+ float explosiveness;
+ float randomness;
+ bool restart_request;
+ AABB custom_aabb;
+ bool use_local_coords;
+ RID process_material;
+
+ RS::ParticlesDrawOrder draw_order;
+
+ Vector<RID> draw_passes;
+
+ RID particle_buffer;
+ RID particle_instance_buffer;
+ RID frame_params_buffer;
+
+ RID particles_material_uniform_set;
+ RID particles_copy_uniform_set;
+ RID particles_transforms_buffer_uniform_set;
+
+ RID particles_sort_buffer;
+ RID particles_sort_uniform_set;
+
+ bool dirty = false;
+ Particles *update_list = nullptr;
+
+ RID sub_emitter;
+
+ float phase;
+ float prev_phase;
+ uint64_t prev_ticks;
+ uint32_t random_seed;
+
+ uint32_t cycle_number;
+
+ float speed_scale;
+
+ int fixed_fps;
+ bool fractional_delta;
+ float frame_remainder;
+
+ bool clear;
+
+ bool force_sub_emit = false;
+
+ Transform emission_transform;
+
+ Vector<uint8_t> emission_buffer_data;
+
+ ParticleEmissionBuffer *emission_buffer = nullptr;
+ RID emission_storage_buffer;
+
+ Particles() :
+ inactive(true),
+ inactive_time(0.0),
+ emitting(false),
+ one_shot(false),
+ amount(0),
+ lifetime(1.0),
+ pre_process_time(0.0),
+ explosiveness(0.0),
+ randomness(0.0),
+ restart_request(false),
+ custom_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8))),
+ use_local_coords(true),
+ draw_order(RS::PARTICLES_DRAW_ORDER_INDEX),
+ prev_ticks(0),
+ random_seed(0),
+ cycle_number(0),
+ speed_scale(1.0),
+ fixed_fps(0),
+ fractional_delta(false),
+ frame_remainder(0),
+ clear(true) {
+ }
+
+ RasterizerScene::InstanceDependency instance_dependency;
+
+ ParticlesFrameParams frame_params;
+ };
+
+ void _particles_process(Particles *p_particles, float p_delta);
+ void _particles_allocate_emission_buffer(Particles *particles);
+ void _particles_free_data(Particles *particles);
+
+ struct ParticlesShader {
+ struct PushConstant {
+ float lifetime;
+ uint32_t clear;
+ uint32_t total_particles;
+ uint32_t trail_size;
+
+ uint32_t use_fractional_delta;
+ uint32_t sub_emitter_mode;
+ uint32_t can_emit;
+ uint32_t pad;
+ };
+
+ ParticlesShaderRD shader;
+ ShaderCompilerRD compiler;
+
+ RID default_shader;
+ RID default_material;
+ RID default_shader_rd;
+
+ RID base_uniform_set;
+
+ struct CopyPushConstant {
+ float sort_direction[3];
+ uint32_t total_particles;
+ };
+
+ enum {
+ COPY_MODE_FILL_INSTANCES,
+ COPY_MODE_FILL_SORT_BUFFER,
+ COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER,
+ COPY_MODE_MAX,
+ };
+
+ ParticlesCopyShaderRD copy_shader;
+ RID copy_shader_version;
+ RID copy_pipelines[COPY_MODE_MAX];
+
+ } particles_shader;
+
+ Particles *particle_update_list = nullptr;
+
+ struct ParticlesShaderData : public ShaderData {
+ bool valid;
+ RID version;
+
+ //RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX];
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String path;
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ RID pipeline;
+
+ bool uses_time;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ ParticlesShaderData();
+ virtual ~ParticlesShaderData();
+ };
+
+ ShaderData *_create_particles_shader_func();
+ static RasterizerStorageRD::ShaderData *_create_particles_shader_funcs() {
+ return base_singleton->_create_particles_shader_func();
+ }
+
+ struct ParticlesMaterialData : public MaterialData {
+ uint64_t last_frame;
+ ParticlesShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ bool uniform_set_updated;
+
+ virtual void set_render_priority(int p_priority) {}
+ virtual void set_next_pass(RID p_pass) {}
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~ParticlesMaterialData();
+ };
+
+ MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader);
+ static RasterizerStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) {
+ return base_singleton->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader));
+ }
+
+ void update_particles();
+
+ mutable RID_Owner<Particles> particles_owner;
+
/* Skeleton */
struct Skeleton {
@@ -732,14 +988,14 @@ public:
virtual RID texture_2d_create(const Ref<Image> &p_image);
virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type);
- virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices); //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent
virtual RID texture_proxy_create(RID p_base);
virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate);
virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); //mostly used for video and streaming
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0);
- virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap);
+ virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data);
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to);
//these two APIs can be used together or in combination with the others.
@@ -749,7 +1005,7 @@ public:
virtual Ref<Image> texture_2d_get(RID p_texture) const;
virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const;
- virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const;
+ virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const;
virtual void texture_replace(RID p_texture, RID p_by_texture);
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height);
@@ -977,6 +1233,19 @@ public:
return s->multimesh_render_index;
}
+ _FORCE_INLINE_ uint32_t mesh_surface_get_particles_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ Mesh::Surface *s = mesh->surfaces[p_surface_index];
+
+ if (s->particles_render_pass != p_render_pass) {
+ (*r_index)++;
+ s->particles_render_pass = p_render_pass;
+ s->particles_render_index = *r_index;
+ }
+
+ return s->particles_render_index;
+ }
+
/* MULTIMESH API */
RID multimesh_create();
@@ -1407,39 +1676,77 @@ public:
/* PARTICLES */
- RID particles_create() { return RID(); }
+ RID particles_create();
- void particles_set_emitting(RID p_particles, bool p_emitting) {}
- void particles_set_amount(RID p_particles, int p_amount) {}
- void particles_set_lifetime(RID p_particles, float p_lifetime) {}
- void particles_set_one_shot(RID p_particles, bool p_one_shot) {}
- void particles_set_pre_process_time(RID p_particles, float p_time) {}
- void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) {}
- void particles_set_randomness_ratio(RID p_particles, float p_ratio) {}
- void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {}
- void particles_set_speed_scale(RID p_particles, float p_scale) {}
- void particles_set_use_local_coordinates(RID p_particles, bool p_enable) {}
- void particles_set_process_material(RID p_particles, RID p_material) {}
- void particles_set_fixed_fps(RID p_particles, int p_fps) {}
- void particles_set_fractional_delta(RID p_particles, bool p_enable) {}
- void particles_restart(RID p_particles) {}
+ void particles_set_emitting(RID p_particles, bool p_emitting);
+ void particles_set_amount(RID p_particles, int p_amount);
+ void particles_set_lifetime(RID p_particles, float p_lifetime);
+ void particles_set_one_shot(RID p_particles, bool p_one_shot);
+ void particles_set_pre_process_time(RID p_particles, float p_time);
+ void particles_set_explosiveness_ratio(RID p_particles, float p_ratio);
+ void particles_set_randomness_ratio(RID p_particles, float p_ratio);
+ void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb);
+ void particles_set_speed_scale(RID p_particles, float p_scale);
+ void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
+ void particles_set_process_material(RID p_particles, RID p_material);
+ void particles_set_fixed_fps(RID p_particles, int p_fps);
+ void particles_set_fractional_delta(RID p_particles, bool p_enable);
+ void particles_restart(RID p_particles);
+ void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
+ void particles_set_subemitter(RID p_particles, RID p_subemitter_particles);
- void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {}
+ void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order);
- void particles_set_draw_passes(RID p_particles, int p_count) {}
- void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {}
+ void particles_set_draw_passes(RID p_particles, int p_count);
+ void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh);
- void particles_request_process(RID p_particles) {}
- AABB particles_get_current_aabb(RID p_particles) { return AABB(); }
- AABB particles_get_aabb(RID p_particles) const { return AABB(); }
+ void particles_request_process(RID p_particles);
+ AABB particles_get_current_aabb(RID p_particles);
+ AABB particles_get_aabb(RID p_particles) const;
- void particles_set_emission_transform(RID p_particles, const Transform &p_transform) {}
+ void particles_set_emission_transform(RID p_particles, const Transform &p_transform);
- bool particles_get_emitting(RID p_particles) { return false; }
- int particles_get_draw_passes(RID p_particles) const { return 0; }
- RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { return RID(); }
+ bool particles_get_emitting(RID p_particles);
+ int particles_get_draw_passes(RID p_particles) const;
+ RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const;
+
+ void particles_set_view_axis(RID p_particles, const Vector3 &p_axis);
+
+ virtual bool particles_is_inactive(RID p_particles) const;
+
+ _FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, 0);
+
+ return particles->amount;
+ }
- virtual bool particles_is_inactive(RID p_particles) const { return false; }
+ _FORCE_INLINE_ uint32_t particles_is_using_local_coords(RID p_particles) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, false);
+
+ return particles->use_local_coords;
+ }
+
+ _FORCE_INLINE_ RID particles_get_instance_buffer_uniform_set(RID p_particles, RID p_shader, uint32_t p_set) {
+ Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, RID());
+ if (particles->particles_transforms_buffer_uniform_set.is_null()) {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(particles->particle_instance_buffer);
+ uniforms.push_back(u);
+ }
+
+ particles->particles_transforms_buffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set);
+ }
+
+ return particles->particles_transforms_buffer_uniform_set;
+ }
/* GLOBAL VARIABLES API */
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
index 1820c39c5a..f70ddbb75a 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
@@ -537,6 +537,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
r_gen_code.vertex_global += struct_code;
r_gen_code.fragment_global += struct_code;
+ r_gen_code.compute_global += struct_code;
}
int max_texture_uniforms = 0;
@@ -591,6 +592,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (SL::is_sampler_type(E->get().type)) {
r_gen_code.vertex_global += ucode;
r_gen_code.fragment_global += ucode;
+ r_gen_code.compute_global += ucode;
GeneratedCode::Texture texture;
texture.name = E->key();
@@ -700,6 +702,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
vcode += ";\n";
r_gen_code.vertex_global += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode;
r_gen_code.fragment_global += "layout(location=" + itos(index) + ") " + interp_mode + "in " + vcode;
+ r_gen_code.compute_global += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode;
index++;
}
@@ -724,6 +727,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
gcode += ";\n";
r_gen_code.vertex_global += gcode;
r_gen_code.fragment_global += gcode;
+ r_gen_code.compute_global += gcode;
}
Map<StringName, String> function_code;
@@ -741,6 +745,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
Set<StringName> added_vtx;
Set<StringName> added_fragment; //share for light
+ Set<StringName> added_compute; //share for light
for (int i = 0; i < pnode->functions.size(); i++) {
SL::FunctionNode *fnode = pnode->functions[i].function;
@@ -763,6 +768,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment);
r_gen_code.light = function_code[light_name];
}
+
+ if (fnode->name == compute_name) {
+ _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.compute_global, added_compute);
+ r_gen_code.compute = function_code[compute_name];
+ }
+
function = nullptr;
}
@@ -1245,6 +1256,8 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide
r_gen_code.vertex_global = String();
r_gen_code.fragment = String();
r_gen_code.fragment_global = String();
+ r_gen_code.compute = String();
+ r_gen_code.compute_global = String();
r_gen_code.light = String();
r_gen_code.uses_fragment_time = false;
r_gen_code.uses_vertex_time = false;
@@ -1266,6 +1279,7 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) {
vertex_name = "vertex";
fragment_name = "fragment";
+ compute_name = "compute";
light_name = "light";
time_name = "TIME";
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
index ce94fb743f..565520ec65 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
@@ -68,6 +68,8 @@ public:
String fragment_global;
String fragment;
String light;
+ String compute_global;
+ String compute;
bool uses_global_textures;
bool uses_fragment_time;
@@ -104,6 +106,7 @@ private:
StringName vertex_name;
StringName fragment_name;
StringName light_name;
+ StringName compute_name;
StringName time_name;
Set<StringName> texture_functions;
diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub
index 3aa863be98..9d531d63ad 100644
--- a/servers/rendering/rasterizer_rd/shaders/SCsub
+++ b/servers/rendering/rasterizer_rd/shaders/SCsub
@@ -37,3 +37,6 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("sdfgi_debug_probes.glsl")
env.RD_GLSL("volumetric_fog.glsl")
env.RD_GLSL("shadow_reduce.glsl")
+ env.RD_GLSL("particles.glsl")
+ env.RD_GLSL("particles_copy.glsl")
+ env.RD_GLSL("sort.glsl")
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
index e33b3face9..4a40584e16 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
@@ -101,7 +101,7 @@ void main() {
offset += 1;
} else {
instance_color = vec4(texelFetch(instancing_buffer, offset + 0), texelFetch(instancing_buffer, offset + 1), texelFetch(instancing_buffer, offset + 2), texelFetch(instancing_buffer, offset + 3));
- offser += 4;
+ offset += 4;
}
color *= instance_color;
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index eb39c28fa9..e565bd8e3d 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -14,6 +14,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define FLAG_FLIP_Y (1 << 5)
#define FLAG_FORCE_LUMINANCE (1 << 6)
#define FLAG_COPY_ALL_SOURCE (1 << 7)
+#define FLAG_HIGH_QUALITY_GLOW (1 << 8)
layout(push_constant, binding = 1, std430) uniform Params {
ivec4 section;
@@ -116,17 +117,42 @@ void main() {
vec4 color = vec4(0.0);
if (bool(params.flags & FLAG_HORIZONTAL)) {
- ivec2 base_pos = (pos + params.section.xy) << 1;
+ ivec2 base_pos = ((pos + params.section.xy) << 1) + ivec2(1);
ivec2 section_begin = params.section.xy << 1;
ivec2 section_end = section_begin + (params.section.zw << 1);
- GLOW_ADD(ivec2(0, 0), 0.174938);
- GLOW_ADD(ivec2(1, 0), 0.165569);
- GLOW_ADD(ivec2(2, 0), 0.140367);
- GLOW_ADD(ivec2(3, 0), 0.106595);
- GLOW_ADD(ivec2(-1, 0), 0.165569);
- GLOW_ADD(ivec2(-2, 0), 0.140367);
- GLOW_ADD(ivec2(-3, 0), 0.106595);
+ if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
+ //Sample from two lines to capture single pixel features
+ GLOW_ADD(ivec2(0, 0), 0.152781);
+ GLOW_ADD(ivec2(1, 0), 0.144599);
+ GLOW_ADD(ivec2(2, 0), 0.122589);
+ GLOW_ADD(ivec2(3, 0), 0.093095);
+ GLOW_ADD(ivec2(4, 0), 0.063327);
+ GLOW_ADD(ivec2(-1, 0), 0.144599);
+ GLOW_ADD(ivec2(-2, 0), 0.122589);
+ GLOW_ADD(ivec2(-3, 0), 0.093095);
+ GLOW_ADD(ivec2(-4, 0), 0.063327);
+
+ GLOW_ADD(ivec2(0, 1), 0.152781);
+ GLOW_ADD(ivec2(1, 1), 0.144599);
+ GLOW_ADD(ivec2(2, 1), 0.122589);
+ GLOW_ADD(ivec2(3, 1), 0.093095);
+ GLOW_ADD(ivec2(4, 1), 0.063327);
+ GLOW_ADD(ivec2(-1, 1), 0.144599);
+ GLOW_ADD(ivec2(-2, 1), 0.122589);
+ GLOW_ADD(ivec2(-3, 1), 0.093095);
+ GLOW_ADD(ivec2(-4, 1), 0.063327);
+ color *= 0.5;
+ } else {
+ GLOW_ADD(ivec2(0, 0), 0.174938);
+ GLOW_ADD(ivec2(1, 0), 0.165569);
+ GLOW_ADD(ivec2(2, 0), 0.140367);
+ GLOW_ADD(ivec2(3, 0), 0.106595);
+ GLOW_ADD(ivec2(-1, 0), 0.165569);
+ GLOW_ADD(ivec2(-2, 0), 0.140367);
+ GLOW_ADD(ivec2(-3, 0), 0.106595);
+ }
+
color *= params.glow_strength;
} else {
ivec2 base_pos = pos + params.section.xy;
diff --git a/servers/rendering/rasterizer_rd/shaders/particles.glsl b/servers/rendering/rasterizer_rd/shaders/particles.glsl
new file mode 100644
index 0000000000..a924509771
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/particles.glsl
@@ -0,0 +1,394 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
+
+#define SAMPLER_NEAREST_CLAMP 0
+#define SAMPLER_LINEAR_CLAMP 1
+#define SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP 2
+#define SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP 3
+#define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_CLAMP 4
+#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_CLAMP 5
+#define SAMPLER_NEAREST_REPEAT 6
+#define SAMPLER_LINEAR_REPEAT 7
+#define SAMPLER_NEAREST_WITH_MIPMAPS_REPEAT 8
+#define SAMPLER_LINEAR_WITH_MIPMAPS_REPEAT 9
+#define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10
+#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11
+
+/* SET 0: GLOBAL DATA */
+
+layout(set = 0, binding = 1) uniform sampler material_samplers[12];
+
+layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData {
+ vec4 data[];
+}
+global_variables;
+
+/* Set 1: FRAME AND PARTICLE DATA */
+
+// a frame history is kept for trail deterministic behavior
+struct FrameParams {
+ bool emitting;
+ float system_phase;
+ float prev_system_phase;
+ uint cycle;
+
+ float explosiveness;
+ float randomness;
+ float time;
+ float delta;
+
+ uint random_seed;
+ uint pad[3];
+
+ mat4 emission_transform;
+};
+
+layout(set = 1, binding = 0, std430) restrict buffer FrameHistory {
+ FrameParams data[];
+}
+frame_history;
+
+struct ParticleData {
+ mat4 xform;
+ vec3 velocity;
+ bool is_active;
+ vec4 color;
+ vec4 custom;
+};
+
+layout(set = 1, binding = 1, std430) restrict buffer Particles {
+ ParticleData data[];
+}
+particles;
+
+#define EMISSION_FLAG_HAS_POSITION 1
+#define EMISSION_FLAG_HAS_ROTATION_SCALE 2
+#define EMISSION_FLAG_HAS_VELOCITY 4
+#define EMISSION_FLAG_HAS_COLOR 8
+#define EMISSION_FLAG_HAS_CUSTOM 16
+
+struct ParticleEmission {
+ mat4 xform;
+ vec3 velocity;
+ uint flags;
+ vec4 color;
+ vec4 custom;
+};
+
+layout(set = 1, binding = 2, std430) restrict volatile coherent buffer SourceEmission {
+ int particle_count;
+ uint pad0;
+ uint pad1;
+ uint pad2;
+ ParticleEmission data[];
+}
+src_particles;
+
+layout(set = 1, binding = 3, std430) restrict volatile coherent buffer DestEmission {
+ int particle_count;
+ int particle_max;
+ uint pad1;
+ uint pad2;
+ ParticleEmission data[];
+}
+dst_particles;
+
+/* SET 2: MATERIAL */
+
+#ifdef USE_MATERIAL_UNIFORMS
+layout(set = 2, binding = 0, std140) uniform MaterialUniforms{
+ /* clang-format off */
+MATERIAL_UNIFORMS
+ /* clang-format on */
+} material;
+#endif
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ float lifetime;
+ bool clear;
+ uint total_particles;
+ uint trail_size;
+ bool use_fractional_delta;
+ bool sub_emitter_mode;
+ bool can_emit;
+ uint pad;
+}
+params;
+
+uint hash(uint x) {
+ x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
+ x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
+ x = (x >> uint(16)) ^ x;
+ return x;
+}
+
+bool emit_particle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) {
+ if (!params.can_emit) {
+ return false;
+ }
+
+ bool valid = false;
+
+ int dst_index = atomicAdd(dst_particles.particle_count, 1);
+
+ if (dst_index >= dst_particles.particle_max) {
+ atomicAdd(dst_particles.particle_count, -1);
+ return false;
+ }
+ /*
+ valid = true;
+
+ int attempts = 256; // never trust compute
+ while(attempts-- > 0) {
+ dst_index = dst_particles.particle_count;
+ if (dst_index == dst_particles.particle_max) {
+ return false; //can't emit anymore
+ }
+
+ if (atomicCompSwap(dst_particles.particle_count, dst_index, dst_index +1 ) != dst_index) {
+ continue;
+ }
+ valid=true;
+ break;
+ }
+
+ barrier();
+
+ if (!valid) {
+ return false; //gave up (attempts exhausted)
+ }
+*/
+ dst_particles.data[dst_index].xform = p_xform;
+ dst_particles.data[dst_index].velocity = p_velocity;
+ dst_particles.data[dst_index].color = p_color;
+ dst_particles.data[dst_index].custom = p_custom;
+ dst_particles.data[dst_index].flags = p_flags;
+
+ return true;
+}
+
+/* clang-format off */
+
+COMPUTE_SHADER_GLOBALS
+
+/* clang-format on */
+
+void main() {
+ uint particle = gl_GlobalInvocationID.x;
+
+ if (particle >= params.total_particles * params.trail_size) {
+ return; //discard
+ }
+
+ uint index = particle / params.trail_size;
+ uint frame = (particle % params.trail_size);
+
+#define FRAME frame_history.data[frame]
+#define PARTICLE particles.data[particle]
+
+ bool apply_forces = true;
+ bool apply_velocity = true;
+ float local_delta = FRAME.delta;
+
+ float mass = 1.0;
+
+ bool restart = false;
+
+ bool restart_position = false;
+ bool restart_rotation_scale = false;
+ bool restart_velocity = false;
+ bool restart_color = false;
+ bool restart_custom = false;
+
+ if (params.clear) {
+ PARTICLE.color = vec4(1.0);
+ PARTICLE.custom = vec4(0.0);
+ PARTICLE.velocity = vec3(0.0);
+ PARTICLE.is_active = false;
+ PARTICLE.xform = mat4(
+ vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 1.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+ }
+
+ if (params.sub_emitter_mode) {
+ if (!PARTICLE.is_active) {
+ int src_index = atomicAdd(src_particles.particle_count, -1) - 1;
+
+ if (src_index >= 0) {
+ PARTICLE.is_active = true;
+ restart = true;
+
+ if (bool(src_particles.data[src_index].flags & EMISSION_FLAG_HAS_POSITION)) {
+ PARTICLE.xform[3] = src_particles.data[src_index].xform[3];
+ } else {
+ PARTICLE.xform[3] = vec4(0, 0, 0, 1);
+ restart_position = true;
+ }
+ if (bool(src_particles.data[src_index].flags & EMISSION_FLAG_HAS_ROTATION_SCALE)) {
+ PARTICLE.xform[0] = src_particles.data[src_index].xform[0];
+ PARTICLE.xform[1] = src_particles.data[src_index].xform[1];
+ PARTICLE.xform[2] = src_particles.data[src_index].xform[2];
+ } else {
+ PARTICLE.xform[0] = vec4(1, 0, 0, 0);
+ PARTICLE.xform[1] = vec4(0, 1, 0, 0);
+ PARTICLE.xform[2] = vec4(0, 0, 1, 0);
+ restart_rotation_scale = true;
+ }
+ if (bool(src_particles.data[src_index].flags & EMISSION_FLAG_HAS_VELOCITY)) {
+ PARTICLE.velocity = src_particles.data[src_index].velocity;
+ } else {
+ PARTICLE.velocity = vec3(0);
+ restart_velocity = true;
+ }
+ if (bool(src_particles.data[src_index].flags & EMISSION_FLAG_HAS_COLOR)) {
+ PARTICLE.color = src_particles.data[src_index].color;
+ } else {
+ PARTICLE.color = vec4(1);
+ restart_color = true;
+ }
+
+ if (bool(src_particles.data[src_index].flags & EMISSION_FLAG_HAS_CUSTOM)) {
+ PARTICLE.custom = src_particles.data[src_index].custom;
+ } else {
+ PARTICLE.custom = vec4(0);
+ restart_custom = true;
+ }
+ }
+ }
+
+ } else if (FRAME.emitting) {
+ float restart_phase = float(index) / float(params.total_particles);
+
+ if (FRAME.randomness > 0.0) {
+ uint seed = FRAME.cycle;
+ if (restart_phase >= FRAME.system_phase) {
+ seed -= uint(1);
+ }
+ seed *= uint(params.total_particles);
+ seed += uint(index);
+ float random = float(hash(seed) % uint(65536)) / 65536.0;
+ restart_phase += FRAME.randomness * random * 1.0 / float(params.total_particles);
+ }
+
+ restart_phase *= (1.0 - FRAME.explosiveness);
+
+ if (FRAME.system_phase > FRAME.prev_system_phase) {
+ // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed
+
+ if (restart_phase >= FRAME.prev_system_phase && restart_phase < FRAME.system_phase) {
+ restart = true;
+ if (params.use_fractional_delta) {
+ local_delta = (FRAME.system_phase - restart_phase) * params.lifetime;
+ }
+ }
+
+ } else if (FRAME.delta > 0.0) {
+ if (restart_phase >= FRAME.prev_system_phase) {
+ restart = true;
+ if (params.use_fractional_delta) {
+ local_delta = (1.0 - restart_phase + FRAME.system_phase) * params.lifetime;
+ }
+
+ } else if (restart_phase < FRAME.system_phase) {
+ restart = true;
+ if (params.use_fractional_delta) {
+ local_delta = (FRAME.system_phase - restart_phase) * params.lifetime;
+ }
+ }
+ }
+
+ uint current_cycle = FRAME.cycle;
+
+ if (FRAME.system_phase < restart_phase) {
+ current_cycle -= uint(1);
+ }
+
+ uint particle_number = current_cycle * uint(params.total_particles) + particle;
+
+ if (restart) {
+ PARTICLE.is_active = FRAME.emitting;
+ restart_position = true;
+ restart_rotation_scale = true;
+ restart_velocity = true;
+ restart_color = true;
+ restart_custom = true;
+ }
+ }
+
+ if (PARTICLE.is_active) {
+ /* clang-format off */
+
+COMPUTE_SHADER_CODE
+
+ /* clang-format on */
+ }
+
+#if !defined(DISABLE_VELOCITY)
+
+ if (PARTICLE.is_active) {
+ PARTICLE.xform[3].xyz += PARTICLE.velocity * local_delta;
+ }
+#endif
+
+#if 0
+ if (PARTICLE.is_active) {
+ //execute shader
+
+
+
+
+ //!defined(DISABLE_FORCE)
+
+ if (false) {
+ vec3 force = vec3(0.0);
+ for (int i = 0; i < attractor_count; i++) {
+ vec3 rel_vec = xform[3].xyz - attractors[i].pos;
+ float dist = length(rel_vec);
+ if (attractors[i].radius < dist)
+ continue;
+ if (attractors[i].eat_radius > 0.0 && attractors[i].eat_radius > dist) {
+ out_velocity_active.a = 0.0;
+ }
+
+ rel_vec = normalize(rel_vec);
+
+ float attenuation = pow(dist / attractors[i].radius, attractors[i].attenuation);
+
+ if (attractors[i].dir == vec3(0.0)) {
+ //towards center
+ force += attractors[i].strength * rel_vec * attenuation * mass;
+ } else {
+ force += attractors[i].strength * attractors[i].dir * attenuation * mass;
+ }
+ }
+
+ out_velocity_active.xyz += force * local_delta;
+ }
+
+#if !defined(DISABLE_VELOCITY)
+
+ if (true) {
+ xform[3].xyz += out_velocity_active.xyz * local_delta;
+ }
+#endif
+ } else {
+ xform = mat4(0.0);
+ }
+
+
+ xform = transpose(xform);
+
+ out_velocity_active.a = mix(0.0, 1.0, shader_active);
+
+ out_xform_1 = xform[0];
+ out_xform_2 = xform[1];
+ out_xform_3 = xform[2];
+#endif
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl b/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl
new file mode 100644
index 0000000000..6c782b6045
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/particles_copy.glsl
@@ -0,0 +1,82 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
+
+struct ParticleData {
+ mat4 xform;
+ vec3 velocity;
+ bool is_active;
+ vec4 color;
+ vec4 custom;
+};
+
+layout(set = 0, binding = 1, std430) restrict readonly buffer Particles {
+ ParticleData data[];
+}
+particles;
+
+layout(set = 0, binding = 2, std430) restrict writeonly buffer Transforms {
+ vec4 data[];
+}
+instances;
+
+#ifdef USE_SORT_BUFFER
+
+layout(set = 1, binding = 0, std430) restrict buffer SortBuffer {
+ vec2 data[];
+}
+sort_buffer;
+
+#endif // USE_SORT_BUFFER
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ vec3 sort_direction;
+ uint total_particles;
+}
+params;
+
+void main() {
+#ifdef MODE_FILL_SORT_BUFFER
+
+ uint particle = gl_GlobalInvocationID.x;
+ if (particle >= params.total_particles) {
+ return; //discard
+ }
+
+ sort_buffer.data[particle].x = dot(params.sort_direction, particles.data[particle].xform[3].xyz);
+ sort_buffer.data[particle].y = float(particle);
+#endif
+
+#ifdef MODE_FILL_INSTANCES
+
+ uint particle = gl_GlobalInvocationID.x;
+ uint write_offset = gl_GlobalInvocationID.x * (3 + 1 + 1); //xform + color + custom
+
+ if (particle >= params.total_particles) {
+ return; //discard
+ }
+
+#ifdef USE_SORT_BUFFER
+ particle = uint(sort_buffer.data[particle].y); //use index from sort buffer
+#endif
+
+ mat4 txform;
+
+ if (particles.data[particle].is_active) {
+ txform = transpose(particles.data[particle].xform);
+ } else {
+ txform = mat4(vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); //zero scale, becomes invisible
+ }
+
+ instances.data[write_offset + 0] = txform[0];
+ instances.data[write_offset + 1] = txform[1];
+ instances.data[write_offset + 2] = txform[2];
+ instances.data[write_offset + 3] = particles.data[particle].color;
+ instances.data[write_offset + 4] = particles.data[particle].custom;
+
+#endif
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
index 5993e68317..e11f3983c5 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
@@ -681,9 +681,13 @@ LIGHT_SHADER_CODE
#ifndef USE_NO_SHADOWS
-// Produces cheap but low-quality white noise, nothing special
+// Produces cheap white noise, optimized for window-space
+// Comes from: https://www.shadertoy.com/view/4djSRW
+// Copyright: Dave Hoskins, MIT License
float quick_hash(vec2 pos) {
- return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
+ vec3 p3 = fract(vec3(pos.xyx) * .1031);
+ p3 += dot(p3, p3.yzx + 33.33);
+ return fract((p3.x + p3.y) * p3.z);
}
float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
index 66bfefbe89..0cc2b90c53 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
@@ -252,7 +252,7 @@ layout(set = 1, binding = 0) uniform textureCube radiance_cubemap;
#endif
-/* Set 2, Reflection and Shadow Atlases (view dependant) */
+/* Set 2, Reflection and Shadow Atlases (view dependent) */
layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas;
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl
index c4b29216d5..61e4bf5e18 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sdfgi_direct_light.glsl
@@ -22,7 +22,7 @@ dispatch_data;
struct ProcessVoxel {
uint position; //xyz 7 bit packed, extra 11 bits for neigbours
uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours
- uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbous
+ uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours
uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours
//total neighbours: 26
};
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl
index 1ec471d204..d516ab22c3 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sdfgi_integrate.glsl
@@ -336,7 +336,7 @@ void main() {
#ifdef MODE_STORE
- // converting to octahedral in this step is requiered because
+ // converting to octahedral in this step is required because
// octahedral is much faster to read from the screen than spherical harmonics,
// despite the very slight quality loss
@@ -512,7 +512,7 @@ void main() {
imageStore(lightprobe_average_scroll_texture, dst_pos, value);
}
} else if (params.cascade < params.max_cascades - 1) {
- //cant scroll, must look for position in parent cascade
+ //can't scroll, must look for position in parent cascade
//to global coords
float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell;
diff --git a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl
index d7d19897e3..916c60ac89 100644
--- a/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sdfgi_preprocess.glsl
@@ -103,7 +103,7 @@ dispatch_data;
struct ProcessVoxel {
uint position; //xyz 7 bit packed, extra 11 bits for neigbours
uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours
- uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbous
+ uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours
uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours
//total neighbours: 26
};
@@ -136,7 +136,7 @@ dispatch_data;
struct ProcessVoxel {
uint position; //xyz 7 bit packed, extra 11 bits for neigbours
uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neibhbours
- uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbous
+ uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours
uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours
//total neighbours: 26
};
@@ -274,7 +274,7 @@ void main() {
#ifdef MODE_JUMPFLOOD
- //regular jumpflood, efficent for large steps, inefficient for small steps
+ //regular jumpflood, efficient for large steps, inefficient for small steps
ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
vec3 posf = vec3(pos);
@@ -338,7 +338,7 @@ void main() {
continue; //was not initialized yet, ignore
}
- float q_dist = distance(posf, vec3(p.xyz));
+ float q_dist = distance(posf, vec3(q.xyz));
if (p.w == 0 || q_dist < p_dist) {
p = q; //just replace because current is unused
p_dist = q_dist;
diff --git a/servers/rendering/rasterizer_rd/shaders/sort.glsl b/servers/rendering/rasterizer_rd/shaders/sort.glsl
new file mode 100644
index 0000000000..e5ebb9c64b
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/sort.glsl
@@ -0,0 +1,203 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+// Original version here:
+// https://github.com/GPUOpen-LibrariesAndSDKs/GPUParticles11/blob/master/gpuparticles11/src/Shaders
+
+//
+// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#define SORT_SIZE 512
+#define NUM_THREADS (SORT_SIZE / 2)
+#define INVERSION (16 * 2 + 8 * 3)
+#define ITERATIONS 1
+
+layout(local_size_x = NUM_THREADS, local_size_y = 1, local_size_z = 1) in;
+
+#ifndef MODE_SORT_STEP
+
+shared vec2 g_LDS[SORT_SIZE];
+
+#endif
+
+layout(set = 1, binding = 0, std430) restrict buffer SortBuffer {
+ vec2 data[];
+}
+sort_buffer;
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ uint total_elements;
+ uint pad[3];
+ ivec4 job_params;
+}
+params;
+
+void main() {
+#ifdef MODE_SORT_BLOCK
+
+ uvec3 Gid = gl_WorkGroupID;
+ uvec3 DTid = gl_GlobalInvocationID;
+ uvec3 GTid = gl_LocalInvocationID;
+ uint GI = gl_LocalInvocationIndex;
+
+ int GlobalBaseIndex = int((Gid.x * SORT_SIZE) + GTid.x);
+ int LocalBaseIndex = int(GI);
+ int numElementsInThreadGroup = int(min(SORT_SIZE, params.total_elements - (Gid.x * SORT_SIZE)));
+
+ // Load shared data
+
+ int i;
+ for (i = 0; i < 2 * ITERATIONS; ++i) {
+ if (GI + i * NUM_THREADS < numElementsInThreadGroup)
+ g_LDS[LocalBaseIndex + i * NUM_THREADS] = sort_buffer.data[GlobalBaseIndex + i * NUM_THREADS];
+ }
+
+ groupMemoryBarrier();
+ barrier();
+
+ // Bitonic sort
+ for (int nMergeSize = 2; nMergeSize <= SORT_SIZE; nMergeSize = nMergeSize * 2) {
+ for (int nMergeSubSize = nMergeSize >> 1; nMergeSubSize > 0; nMergeSubSize = nMergeSubSize >> 1) {
+ for (i = 0; i < ITERATIONS; ++i) {
+ int tmp_index = int(GI + NUM_THREADS * i);
+ int index_low = tmp_index & (nMergeSubSize - 1);
+ int index_high = 2 * (tmp_index - index_low);
+ int index = index_high + index_low;
+
+ int nSwapElem = nMergeSubSize == nMergeSize >> 1 ? index_high + (2 * nMergeSubSize - 1) - index_low : index_high + nMergeSubSize + index_low;
+ if (nSwapElem < numElementsInThreadGroup) {
+ vec2 a = g_LDS[index];
+ vec2 b = g_LDS[nSwapElem];
+
+ if (a.x > b.x) {
+ g_LDS[index] = b;
+ g_LDS[nSwapElem] = a;
+ }
+ }
+ groupMemoryBarrier();
+ barrier();
+ }
+ }
+ }
+
+ // Store shared data
+ for (i = 0; i < 2 * ITERATIONS; ++i) {
+ if (GI + i * NUM_THREADS < numElementsInThreadGroup) {
+ sort_buffer.data[GlobalBaseIndex + i * NUM_THREADS] = g_LDS[LocalBaseIndex + i * NUM_THREADS];
+ }
+ }
+
+#endif
+
+#ifdef MODE_SORT_STEP
+
+ uvec3 Gid = gl_WorkGroupID;
+ uvec3 GTid = gl_LocalInvocationID;
+
+ ivec4 tgp;
+
+ tgp.x = int(Gid.x) * 256;
+ tgp.y = 0;
+ tgp.z = int(params.total_elements);
+ tgp.w = min(512, max(0, tgp.z - int(Gid.x) * 512));
+
+ uint localID = int(tgp.x) + GTid.x; // calculate threadID within this sortable-array
+
+ uint index_low = localID & (params.job_params.x - 1);
+ uint index_high = 2 * (localID - index_low);
+
+ uint index = tgp.y + index_high + index_low;
+ uint nSwapElem = tgp.y + index_high + params.job_params.y + params.job_params.z * index_low;
+
+ if (nSwapElem < tgp.y + tgp.z) {
+ vec2 a = sort_buffer.data[index];
+ vec2 b = sort_buffer.data[nSwapElem];
+
+ if (a.x > b.x) {
+ sort_buffer.data[index] = b;
+ sort_buffer.data[nSwapElem] = a;
+ }
+ }
+
+#endif
+
+#ifdef MODE_SORT_INNER
+
+ uvec3 Gid = gl_WorkGroupID;
+ uvec3 DTid = gl_GlobalInvocationID;
+ uvec3 GTid = gl_LocalInvocationID;
+ uint GI = gl_LocalInvocationIndex;
+
+ ivec4 tgp;
+
+ tgp.x = int(Gid.x * 256);
+ tgp.y = 0;
+ tgp.z = int(params.total_elements.x);
+ tgp.w = int(min(512, max(0, params.total_elements - Gid.x * 512)));
+
+ int GlobalBaseIndex = int(tgp.y + tgp.x * 2 + GTid.x);
+ int LocalBaseIndex = int(GI);
+ int i;
+
+ // Load shared data
+ for (i = 0; i < 2; ++i) {
+ if (GI + i * NUM_THREADS < tgp.w)
+ g_LDS[LocalBaseIndex + i * NUM_THREADS] = sort_buffer.data[GlobalBaseIndex + i * NUM_THREADS];
+ }
+
+ groupMemoryBarrier();
+ barrier();
+
+ // sort threadgroup shared memory
+ for (int nMergeSubSize = SORT_SIZE >> 1; nMergeSubSize > 0; nMergeSubSize = nMergeSubSize >> 1) {
+ int tmp_index = int(GI);
+ int index_low = tmp_index & (nMergeSubSize - 1);
+ int index_high = 2 * (tmp_index - index_low);
+ int index = index_high + index_low;
+
+ int nSwapElem = index_high + nMergeSubSize + index_low;
+
+ if (nSwapElem < tgp.w) {
+ vec2 a = g_LDS[index];
+ vec2 b = g_LDS[nSwapElem];
+
+ if (a.x > b.x) {
+ g_LDS[index] = b;
+ g_LDS[nSwapElem] = a;
+ }
+ }
+ groupMemoryBarrier();
+ barrier();
+ }
+
+ // Store shared data
+ for (i = 0; i < 2; ++i) {
+ if (GI + i * NUM_THREADS < tgp.w) {
+ sort_buffer.data[GlobalBaseIndex + i * NUM_THREADS] = g_LDS[LocalBaseIndex + i * NUM_THREADS];
+ }
+ }
+
+#endif
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl b/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl
index cb19fb0b69..13b162f0c9 100644
--- a/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/volumetric_fog.glsl
@@ -485,7 +485,7 @@ void main() {
//get depth at cell pos
float z = get_depth_at_pos(fog_cell_size.z, i);
- //get distance from previos pos
+ //get distance from previous pos
float d = abs(prev_z - z);
//compute exinction based on beer's
float extinction = t * exp(-d * fog.a);
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp
index 5c0741bb3b..b3d5b0ad83 100644
--- a/servers/rendering/rendering_server_canvas.cpp
+++ b/servers/rendering/rendering_server_canvas.cpp
@@ -81,6 +81,7 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo
child_items[i]->ysort_xform = p_transform;
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]);
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
+ child_items[i]->ysort_index = r_index;
}
r_index++;
@@ -900,13 +901,12 @@ void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skelet
void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) {
- if (p_enable) {
- canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer);
- } else {
- memdelete(canvas_item->copy_back_buffer);
- canvas_item->copy_back_buffer = nullptr;
- }
+ if (p_enable && (canvas_item->copy_back_buffer == nullptr)) {
+ canvas_item->copy_back_buffer = memnew(RasterizerCanvas::Item::CopyBackBuffer);
+ }
+ if (!p_enable && (canvas_item->copy_back_buffer != nullptr)) {
+ memdelete(canvas_item->copy_back_buffer);
+ canvas_item->copy_back_buffer = nullptr;
}
if (p_enable) {
diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h
index 59c0d1fa52..cebe32fba0 100644
--- a/servers/rendering/rendering_server_canvas.h
+++ b/servers/rendering/rendering_server_canvas.h
@@ -51,6 +51,7 @@ public:
Color ysort_modulate;
Transform2D ysort_xform;
Vector2 ysort_pos;
+ int ysort_index;
RS::CanvasItemTextureFilter texture_filter;
RS::CanvasItemTextureRepeat texture_repeat;
@@ -69,6 +70,7 @@ public:
ysort_children_count = -1;
ysort_xform = Transform2D();
ysort_pos = Vector2();
+ ysort_index = 0;
texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
}
@@ -83,7 +85,7 @@ public:
struct ItemPtrSort {
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) {
- return p_left->ysort_pos.x < p_right->ysort_pos.x;
+ return p_left->ysort_index < p_right->ysort_index;
}
return p_left->ysort_pos.y < p_right->ysort_pos.y;
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index b4eac8cd76..b554425bef 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -114,6 +114,14 @@ public:
m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
+#define BIND5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); }
+#define BIND5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); }
+#define BIND6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); }
+#define BIND6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); }
#define BIND0(m_name) \
void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); }
@@ -160,14 +168,14 @@ public:
//these go pass-through, as they can be called from any thread
BIND1R(RID, texture_2d_create, const Ref<Image> &)
BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType)
- BIND1R(RID, texture_3d_create, const Vector<Ref<Image>> &)
+ BIND6R(RID, texture_3d_create, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
BIND1R(RID, texture_proxy_create, RID)
//goes pass-through
BIND3(texture_2d_update_immediate, RID, const Ref<Image> &, int)
//these go through command queue if they are in another thread
BIND3(texture_2d_update, RID, const Ref<Image> &, int)
- BIND4(texture_3d_update, RID, const Ref<Image> &, int, int)
+ BIND2(texture_3d_update, RID, const Vector<Ref<Image>> &)
BIND2(texture_proxy_update, RID, RID)
//these also go pass-through
@@ -177,7 +185,7 @@ public:
BIND1RC(Ref<Image>, texture_2d_get, RID)
BIND2RC(Ref<Image>, texture_2d_layer_get, RID, int)
- BIND3RC(Ref<Image>, texture_3d_slice_get, RID, int, int)
+ BIND1RC(Vector<Ref<Image>>, texture_3d_get, RID)
BIND2(texture_replace, RID, RID)
@@ -442,6 +450,8 @@ public:
BIND1R(bool, particles_is_inactive, RID)
BIND1(particles_request_process, RID)
BIND1(particles_restart, RID)
+ BIND6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t)
+ BIND2(particles_set_subemitter, RID, RID)
BIND2(particles_set_draw_order, RID, RS::ParticlesDrawOrder)
@@ -557,6 +567,7 @@ public:
BIND11(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
BIND1(environment_glow_set_use_bicubic_upscale, bool)
+ BIND1(environment_glow_set_use_high_quality, bool)
BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp
index 2024f5b983..d8e52a5aae 100644
--- a/servers/rendering/rendering_server_scene.cpp
+++ b/servers/rendering/rendering_server_scene.cpp
@@ -2044,6 +2044,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
keep = false;
} else {
RSG::storage->particles_request_process(ins->base);
+ RSG::storage->particles_set_view_axis(ins->base, -p_cam_transform.basis.get_axis(2).normalized());
//particles visible? request redraw
RenderingServerRaster::redraw_request();
}
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index fb5c161c8a..372a7269dc 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -79,14 +79,14 @@ public:
//these go pass-through, as they can be called from any thread
virtual RID texture_2d_create(const Ref<Image> &p_image) { return rendering_server->texture_2d_create(p_image); }
virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return rendering_server->texture_2d_layered_create(p_layers, p_layered_type); }
- virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) { return rendering_server->texture_3d_create(p_slices); }
+ virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { return rendering_server->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); }
virtual RID texture_proxy_create(RID p_base) { return rendering_server->texture_proxy_create(p_base); }
//goes pass-through
virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) { rendering_server->texture_2d_update_immediate(p_texture, p_image, p_layer); }
//these go through command queue if they are in another thread
FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
- FUNC4(texture_3d_update, RID, const Ref<Image> &, int, int)
+ FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
FUNC2(texture_proxy_update, RID, RID)
//these also go pass-through
@@ -96,7 +96,7 @@ public:
FUNC1RC(Ref<Image>, texture_2d_get, RID)
FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int)
- FUNC3RC(Ref<Image>, texture_3d_slice_get, RID, int, int)
+ FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID)
FUNC2(texture_replace, RID, RID)
@@ -360,11 +360,14 @@ public:
FUNC1(particles_request_process, RID)
FUNC1(particles_restart, RID)
+ FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t)
+
FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder)
FUNC2(particles_set_draw_passes, RID, int)
FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
FUNC2(particles_set_emission_transform, RID, const Transform &)
+ FUNC2(particles_set_subemitter, RID, RID)
FUNC1R(AABB, particles_get_current_aabb, RID)
@@ -474,6 +477,7 @@ public:
FUNC11(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
+ FUNC1(environment_glow_set_use_high_quality, bool)
FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index d6acad83f7..6c835fcadf 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -33,15 +33,15 @@
#include "core/print_string.h"
#include "servers/rendering_server.h"
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-static bool _is_number(CharType c) {
+static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
}
-static bool _is_hex(CharType c) {
+static bool _is_hex(char32_t c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
@@ -334,7 +334,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
};
ShaderLanguage::Token ShaderLanguage::_get_token() {
-#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : char32_t(0))
while (true) {
char_idx++;
@@ -582,11 +582,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
break;
}
- str += CharType(GETCHAR(i));
+ str += char32_t(GETCHAR(i));
i++;
}
- CharType last_char = str[str.length() - 1];
+ char32_t last_char = str[str.length() - 1];
if (hexa_found) {
//integer(hex)
@@ -663,7 +663,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
String str;
while (_is_text_char(GETCHAR(0))) {
- str += CharType(GETCHAR(0));
+ str += char32_t(GETCHAR(0));
char_idx++;
}
@@ -920,13 +920,13 @@ void ShaderLanguage::clear() {
}
}
-bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, 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, StringName *r_struct_name) {
- if (p_builtin_types.has(p_identifier)) {
+bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
+ if (p_function_info.built_ins.has(p_identifier)) {
if (r_data_type) {
- *r_data_type = p_builtin_types[p_identifier].type;
+ *r_data_type = p_function_info.built_ins[p_identifier].type;
}
if (r_is_const) {
- *r_is_const = p_builtin_types[p_identifier].constant;
+ *r_is_const = p_function_info.built_ins[p_identifier].constant;
}
if (r_type) {
*r_type = IDENTIFIER_BUILTIN_VAR;
@@ -935,6 +935,20 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
return true;
}
+ if (p_function_info.stage_functions.has(p_identifier)) {
+ if (r_data_type) {
+ *r_data_type = p_function_info.stage_functions[p_identifier].return_type;
+ }
+ if (r_is_const) {
+ *r_is_const = true;
+ }
+ if (r_type) {
+ *r_type = IDENTIFIER_FUNCTION;
+ }
+
+ return true;
+ }
+
FunctionNode *function = nullptr;
while (p_block) {
@@ -2152,7 +2166,7 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[]
{ nullptr, 0 }
};
-bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
+bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
Vector<DataType> args;
@@ -2169,6 +2183,30 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
int argcount = args.size();
+ if (p_function_info.stage_functions.has(name)) {
+ //stage based function
+ const StageFunctionInfo &sf = p_function_info.stage_functions[name];
+ if (argcount != sf.arguments.size()) {
+ _set_error(vformat("Invalid number of arguments when calling stage function '%s', which expects %d arguments.", String(name), sf.arguments.size()));
+ return false;
+ }
+ //validate arguments
+ for (int i = 0; i < argcount; i++) {
+ if (args[i] != sf.arguments[i].type) {
+ _set_error(vformat("Invalid argument type when calling stage function '%s', type expected is '%s'.", String(name), String(get_datatype_name(sf.arguments[i].type))));
+ return false;
+ }
+ }
+
+ if (r_ret_type) {
+ *r_ret_type = sf.return_type;
+ }
+ if (r_ret_type_str) {
+ *r_ret_type_str = "";
+ }
+ return true;
+ }
+
bool failed_builtin = false;
bool unsupported_builtin = false;
int builtin_idx = 0;
@@ -2241,8 +2279,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
if (shader->uniforms.has(varname)) {
fail = true;
} else {
- if (p_builtin_types.has(varname)) {
- BuiltInInfo info = p_builtin_types[varname];
+ if (p_function_info.built_ins.has(varname)) {
+ BuiltInInfo info = p_function_info.built_ins[varname];
if (info.constant) {
fail = true;
}
@@ -2278,7 +2316,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
const BlockNode *b = p_block;
bool valid = false;
while (b) {
- if (b->variables.has(var_name) || p_builtin_types.has(var_name)) {
+ if (b->variables.has(var_name) || p_function_info.built_ins.has(var_name)) {
valid = true;
break;
}
@@ -2353,10 +2391,13 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
err += ",";
}
- if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) {
- err += "-";
+ String arg_name;
+ if (args[i] == TYPE_STRUCT) {
+ arg_name = args2[i];
+ } else {
+ arg_name = get_datatype_name(args[i]);
}
- err += get_datatype_name(args[i]);
+ err += arg_name;
}
err += ")";
_set_error(err);
@@ -2380,6 +2421,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
return false;
}
+ int last_arg_count = 0;
+ String arg_list = "";
+
for (int i = 0; i < shader->functions.size(); i++) {
if (name != shader->functions[i].name) {
continue;
@@ -2391,21 +2435,45 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
FunctionNode *pfunc = shader->functions[i].function;
+ if (arg_list == "") {
+ for (int j = 0; j < pfunc->arguments.size(); j++) {
+ if (j > 0) {
+ arg_list += ", ";
+ }
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ arg_list += func_arg_name;
+ }
+ }
if (pfunc->arguments.size() != args.size()) {
+ last_arg_count = pfunc->arguments.size();
continue;
}
bool fail = false;
for (int j = 0; j < args.size(); j++) {
- if (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) {
- fail = true;
- break;
- }
if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) {
//all good, but it needs implicit conversion later
- } else if (args[j] != pfunc->arguments[j].type) {
+ } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str)) {
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ String arg_name;
+ if (args[j] == TYPE_STRUCT) {
+ arg_name = args2[j];
+ } else {
+ arg_name = get_datatype_name(args[j]);
+ }
+ _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name));
fail = true;
break;
}
@@ -2441,6 +2509,12 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
}
+ if (last_arg_count > args.size()) {
+ _set_error(vformat("Too few arguments for \"%s(%s)\" call. Expected at least %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ } else if (last_arg_count < args.size()) {
+ _set_error(vformat("Too many arguments for \"%s(%s)\" call. Expected at most %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ }
+
return false;
}
@@ -2456,7 +2530,7 @@ bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const {
return true;
}
-bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) {
+bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) {
TkPos pos = _get_tkpos();
Token tk = _get_token();
@@ -2478,7 +2552,7 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
}
}
- Node *arg = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *arg = _parse_and_reduce_expression(p_block, p_function_info);
if (!arg) {
return false;
@@ -3017,16 +3091,16 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
return false;
}
-bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) {
+bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) {
if (p_node->type == Node::TYPE_OPERATOR) {
OperatorNode *op = static_cast<OperatorNode *>(p_node);
if (op->op == OP_INDEX) {
- return _validate_assign(op->arguments[0], p_builtin_types, r_message);
+ return _validate_assign(op->arguments[0], p_function_info, r_message);
} else if (_is_operator_assign(op->op)) {
//chained assignment
- return _validate_assign(op->arguments[1], p_builtin_types, r_message);
+ return _validate_assign(op->arguments[1], p_function_info, r_message);
} else if (op->op == OP_CALL) {
if (r_message) {
@@ -3045,7 +3119,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
- return _validate_assign(member->owner, p_builtin_types, r_message);
+ return _validate_assign(member->owner, p_function_info, r_message);
} else if (p_node->type == Node::TYPE_VARIABLE) {
VariableNode *var = static_cast<VariableNode *>(p_node);
@@ -3071,7 +3145,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
- if (!(p_builtin_types.has(var->name) && p_builtin_types[var->name].constant)) {
+ if (!(p_function_info.built_ins.has(var->name) && p_function_info.built_ins[var->name].constant)) {
return true;
}
} else if (p_node->type == Node::TYPE_ARRAY) {
@@ -3168,7 +3242,7 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_V(false); //bug? function not found
}
-ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
+ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
Vector<Expression> expression;
//Vector<TokenType> operators;
@@ -3184,7 +3258,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PARENTHESIS_OPEN) {
//handle subexpression
- expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return nullptr;
}
@@ -3257,7 +3331,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
int carg = -1;
- bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
if (carg >= 0) {
completion_type = COMPLETION_CALL_ARGUMENTS;
@@ -3271,7 +3345,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
+ if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching constructor found for: '" + String(funcname->name) + "'");
return nullptr;
}
@@ -3347,7 +3421,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return nullptr;
@@ -3408,7 +3482,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return nullptr;
}
@@ -3448,7 +3522,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
nexpr = an;
} else {
- nexpr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ nexpr = _parse_and_reduce_expression(p_block, p_function_info);
if (!nexpr) {
return nullptr;
}
@@ -3490,7 +3564,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
int carg = -1;
- bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
// Check if block has a variable with the same name as function to prevent shader crash.
ShaderLanguage::BlockNode *bnode = p_block;
@@ -3532,7 +3606,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
+ if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching function found for: '" + String(funcname->name) + "'");
return nullptr;
}
@@ -3584,8 +3658,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (shader->uniforms.has(varname)) {
error = true;
} else {
- if (p_builtin_types.has(varname)) {
- BuiltInInfo info = p_builtin_types[varname];
+ if (p_function_info.built_ins.has(varname)) {
+ BuiltInInfo info = p_function_info.built_ins[varname];
if (info.constant) {
error = true;
}
@@ -3617,7 +3691,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat)) {
return nullptr;
}
- } else if (p_builtin_types.has(varname)) {
+ } else if (p_function_info.built_ins.has(varname)) {
//a built-in
if (!_propagate_function_call_sampler_builtin_reference(name, i, varname)) {
return nullptr;
@@ -3672,7 +3746,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
} else {
- if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
+ if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
_set_error("Unknown identifier in expression: " + String(identifier));
return nullptr;
}
@@ -3697,7 +3771,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PERIOD) {
completion_class = TAG_ARRAY;
p_block->block_tag = SubClassTag::TAG_ARRAY;
- call_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ call_expression = _parse_and_reduce_expression(p_block, p_function_info);
p_block->block_tag = SubClassTag::TAG_GLOBAL;
if (!call_expression) {
return nullptr;
@@ -3705,7 +3779,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
data_type = call_expression->get_datatype();
} else { // indexing
- index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ index_expression = _parse_and_reduce_expression(p_block, p_function_info);
if (!index_expression) {
return nullptr;
}
@@ -3869,7 +3943,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -3933,7 +4007,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -4000,7 +4074,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -4085,7 +4159,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Nested array length() is not yet implemented");
return nullptr;
} else if (tk.type == TK_BRACKET_OPEN) {
- Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *index_expression = _parse_and_reduce_expression(p_block, p_function_info);
if (!index_expression) {
return nullptr;
}
@@ -4134,7 +4208,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
*/
} else if (tk.type == TK_BRACKET_OPEN) {
- Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *index = _parse_and_reduce_expression(p_block, p_function_info);
if (!index) {
return nullptr;
}
@@ -4276,7 +4350,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
- if (!_validate_assign(expr, p_builtin_types)) {
+ if (!_validate_assign(expr, p_function_info)) {
_set_error("Invalid use of increment/decrement operator in constant expression.");
return nullptr;
}
@@ -4574,7 +4648,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (int i = expr_pos - 1; i >= next_op; i--) {
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
- if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) {
+ if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info)) {
_set_error("Can't use increment/decrement operator in constant expression.");
return nullptr;
}
@@ -4648,7 +4722,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (_is_operator_assign(op->op)) {
String assign_message;
- if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) {
+ if (!_validate_assign(expression[next_op - 1].node, p_function_info, &assign_message)) {
_set_error(assign_message);
return nullptr;
}
@@ -4802,8 +4876,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
return p_node;
}
-ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
- ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types);
+ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
+ ShaderLanguage::Node *expr = _parse_expression(p_block, p_function_info);
if (!expr) { //errored
return nullptr;
}
@@ -4813,7 +4887,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_
return expr;
}
-Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) {
+Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one, bool p_can_break, bool p_can_continue) {
while (true) {
TkPos pos = _get_tkpos();
@@ -4897,7 +4971,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
StringName name = tk.text;
ShaderLanguage::IdentifierType itype;
- if (_find_identifier(p_block, true, p_builtin_types, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
+ if (_find_identifier(p_block, true, p_function_info, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
@@ -5016,7 +5090,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -5097,7 +5171,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5169,7 +5243,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
decl.initializer = nullptr;
//variable created with assignment! must parse an expression
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5229,7 +5303,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
//a sub block, just because..
BlockNode *block = alloc_node<BlockNode>();
block->parent_block = p_block;
- if (_parse_block(block, p_builtin_types, false, p_can_break, p_can_continue) != OK) {
+ if (_parse_block(block, p_function_info, false, p_can_break, p_can_continue) != OK) {
return ERR_PARSE_ERROR;
}
p_block->statements.push_back(block);
@@ -5243,7 +5317,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_IF;
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5265,7 +5339,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ Error err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
if (err) {
return err;
}
@@ -5276,7 +5350,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
block = alloc_node<BlockNode>();
block->parent_block = p_block;
cf->blocks.push_back(block);
- err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
} else {
_set_tkpos(pos); //rollback
@@ -5295,7 +5369,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_SWITCH;
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5323,7 +5397,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
int prev_type = TK_CF_CASE;
while (true) { // Go-through multiple cases.
- if (_parse_block(switch_block, p_builtin_types, true, true, false) != OK) {
+ if (_parse_block(switch_block, p_function_info, true, true, false) != OK) {
return ERR_PARSE_ERROR;
}
pos = _get_tkpos();
@@ -5424,7 +5498,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(case_block);
p_block->statements.push_back(cf);
- Error err = _parse_block(case_block, p_builtin_types, false, true, false);
+ Error err = _parse_block(case_block, p_function_info, false, true, false);
if (err) {
return err;
}
@@ -5458,7 +5532,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(default_block);
p_block->statements.push_back(cf);
- Error err = _parse_block(default_block, p_builtin_types, false, true, false);
+ Error err = _parse_block(default_block, p_function_info, false, true, false);
if (err) {
return err;
}
@@ -5475,7 +5549,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
do_block = alloc_node<BlockNode>();
do_block->parent_block = p_block;
- Error err = _parse_block(do_block, p_builtin_types, true, true, true);
+ Error err = _parse_block(do_block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5499,7 +5573,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
cf->flow_op = FLOW_OP_WHILE;
}
- Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5516,7 +5590,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, true, true);
+ Error err = _parse_block(block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5547,11 +5621,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
init_block->parent_block = p_block;
init_block->single_statement = true;
cf->blocks.push_back(init_block);
- if (_parse_block(init_block, p_builtin_types, true, false, false) != OK) {
+ if (_parse_block(init_block, p_function_info, true, false, false) != OK) {
return ERR_PARSE_ERROR;
}
- Node *n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ Node *n = _parse_and_reduce_expression(init_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5569,7 +5643,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->expressions.push_back(n);
- n = _parse_and_reduce_expression(init_block, p_builtin_types);
+ n = _parse_and_reduce_expression(init_block, p_function_info);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5587,7 +5661,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, true, true);
+ Error err = _parse_block(block, p_function_info, true, true, true);
if (err) {
return err;
}
@@ -5623,7 +5697,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
} else {
_set_tkpos(pos); //rollback, wants expression
- Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -5725,7 +5799,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
//nothing else, so expression
_set_tkpos(pos); //rollback
- Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -6025,6 +6099,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
case TK_UNIFORM:
case TK_VARYING: {
bool uniform = tk.type == TK_UNIFORM;
+
+ if (!uniform) {
+ if (shader_type_identifier == "particles" || shader_type_identifier == "sky") {
+ _set_error(vformat("Varyings cannot be used in '%s' shaders!", shader_type_identifier));
+ return ERR_PARSE_ERROR;
+ }
+ }
+
DataPrecision precision = PRECISION_DEFAULT;
DataInterpolation interpolation = INTERPOLATION_SMOOTH;
DataType type;
@@ -6066,7 +6148,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
name = tk.text;
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6315,7 +6397,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//reset scope for next uniform
if (tk.type == TK_OP_ASSIGN) {
- Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
+ Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -6440,7 +6522,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6553,7 +6635,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -6634,7 +6716,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -6689,7 +6771,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ Node *expr = _parse_and_reduce_expression(NULL, FunctionInfo());
if (!expr)
return ERR_PARSE_ERROR;
if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
@@ -6726,7 +6808,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, Map<StringName, BuiltInInfo>(), name)) {
+ if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -6749,14 +6831,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
break;
}
- Map<StringName, BuiltInInfo> builtin_types;
+ FunctionInfo builtins;
if (p_functions.has(name)) {
- builtin_types = p_functions[name].built_ins;
+ builtins = p_functions[name];
}
if (p_functions.has("global")) { // Adds global variables: 'TIME'
for (Map<StringName, BuiltInInfo>::Element *E = p_functions["global"].built_ins.front(); E; E = E->next()) {
- builtin_types.insert(E->key(), E->value());
+ builtins.built_ins.insert(E->key(), E->value());
}
}
@@ -6879,7 +6961,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
pname = tk.text;
ShaderLanguage::IdentifierType itype;
- if (_find_identifier(func_node->body, false, builtin_types, pname, (ShaderLanguage::DataType *)nullptr, &itype)) {
+ if (_find_identifier(func_node->body, false, builtins, pname, (ShaderLanguage::DataType *)nullptr, &itype)) {
if (itype != IDENTIFIER_FUNCTION) {
_set_error("Redefinition of '" + String(pname) + "'");
return ERR_PARSE_ERROR;
@@ -6941,7 +7023,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
current_function = name;
- Error err = _parse_block(func_node->body, builtin_types);
+ Error err = _parse_block(func_node->body, builtins);
if (err) {
return err;
}
@@ -6979,6 +7061,11 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI
return true;
}
}
+ if (p_functions.has("compute")) {
+ if (p_functions["compute"].built_ins.has(p_name)) {
+ return true;
+ }
+ }
return false;
}
@@ -7034,7 +7121,7 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat
static int _get_first_ident_pos(const String &p_code) {
int idx = 0;
-#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : char32_t(0))
while (true) {
if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
@@ -7295,7 +7382,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (shader->functions[i].function->arguments[j].is_const) {
@@ -7315,7 +7402,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += shader->functions[i].function->arguments[j].name;
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
}
@@ -7378,7 +7465,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (out_arg >= 0 && i == out_arg) {
@@ -7388,7 +7475,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += get_datatype_name(builtin_func_defs[idx].args[i]);
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
found_arg = true;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index faf06a9a85..0d044a21c7 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -730,8 +730,25 @@ public:
constant(p_constant) {}
};
+ struct StageFunctionInfo {
+ struct Argument {
+ StringName name;
+ DataType type;
+
+ Argument(const StringName &p_name = StringName(), DataType p_type = TYPE_VOID) {
+ name = p_name;
+ type = p_type;
+ }
+ };
+
+ Vector<Argument> arguments;
+ DataType return_type = TYPE_VOID;
+ };
+
struct FunctionInfo {
Map<StringName, BuiltInInfo> built_ins;
+ Map<StringName, StageFunctionInfo> stage_functions;
+
bool can_discard;
};
static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name);
@@ -802,9 +819,9 @@ private:
IDENTIFIER_CONSTANT,
};
- bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr);
+ bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr);
bool _is_operator_assign(Operator p_op) const;
- bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = nullptr);
+ bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
struct BuiltinFuncDef {
@@ -837,16 +854,16 @@ private:
Error _validate_datatype(DataType p_type);
bool _compare_datatypes_in_nodes(Node *a, Node *b) const;
- bool _validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
- bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = nullptr);
+ bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
+ bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr);
bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat);
bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin);
- Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
+ Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
- Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
- 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);
+ Node *_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+ Error _parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
String _get_shader_type_list(const Set<String> &p_shader_types) const;
String _get_qualifier_str(ArgumentQualifier p_qualifier) const;
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 76aeb5989c..ad5cbc9e51 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -145,7 +145,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
- shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3);
+ shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["SHADOW_ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["BACKLIGHT"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT);
@@ -270,20 +271,41 @@ ShaderTypes::ShaderTypes() {
/************ PARTICLES **************************/
shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
- shader_modes[RS::SHADER_PARTICLES].functions["vertex"].can_discard = false;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_ROT_SCALE"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_VELOCITY"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_COLOR"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_CUSTOM"] = constt(ShaderLanguage::TYPE_UINT);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_POSITION"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_ROT_SCALE"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_VELOCITY"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_COLOR"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_CUSTOM"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].can_discard = false;
+
+ {
+ ShaderLanguage::StageFunctionInfo emit_vertex_func;
+ emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("xform", ShaderLanguage::TYPE_MAT4));
+ emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("velocity", ShaderLanguage::TYPE_VEC3));
+ emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("color", ShaderLanguage::TYPE_VEC4));
+ emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4));
+ emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT));
+ emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_particle"] = emit_vertex_func;
+ }
shader_modes[RS::SHADER_PARTICLES].modes.push_back("disable_force");
shader_modes[RS::SHADER_PARTICLES].modes.push_back("disable_velocity");
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 3b034da3aa..9ad19e4b38 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1505,9 +1505,14 @@ ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_dataty
}
}
+RenderingDevice *RenderingServer::create_local_rendering_device() const {
+ return RenderingDevice::get_singleton()->create_local_device();
+}
+
void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_sync"), &RenderingServer::sync);
ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers", "frame_step"), &RenderingServer::draw, DEFVAL(true), DEFVAL(0.0));
+ ClassDB::bind_method(D_METHOD("create_local_rendering_device"), &RenderingServer::create_local_rendering_device);
#ifndef _MSC_VER
#warning TODO all texture methods need re-binding
@@ -2387,6 +2392,7 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)"));
GLOBAL_DEF("rendering/quality/glow/upscale_mode.mobile", 0);
+ GLOBAL_DEF("rendering/quality/glow/use_high_quality", false);
GLOBAL_DEF("rendering/quality/screen_space_reflection/roughness_quality", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/quality/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)"));
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index a13fd4954b..7dae45f126 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -39,6 +39,7 @@
#include "core/typed_array.h"
#include "core/variant.h"
#include "servers/display_server.h"
+#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_language.h"
class RenderingServer : public Object {
@@ -97,12 +98,12 @@ public:
virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_create(const Vector<Ref<Image>> &p_slices) = 0; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; //all slices, then all the mipmaps, must be coherent
virtual RID texture_proxy_create(RID p_base) = 0;
virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
- virtual void texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) = 0;
+ virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
//these two APIs can be used together or in combination with the others.
@@ -112,7 +113,7 @@ public:
virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0;
- virtual Ref<Image> texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const = 0;
+ virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0;
virtual void texture_replace(RID p_texture, RID p_by_texture) = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -563,7 +564,7 @@ public:
virtual RID particles_create() = 0;
- virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
+ virtual void particles_set_emitting(RID p_particles, bool p_enable) = 0;
virtual bool particles_get_emitting(RID p_particles) = 0;
virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
@@ -581,6 +582,18 @@ public:
virtual void particles_request_process(RID p_particles) = 0;
virtual void particles_restart(RID p_particles) = 0;
+ virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) = 0;
+
+ enum ParticlesEmitFlags {
+ PARTICLES_EMIT_FLAG_POSITION = 1,
+ PARTICLES_EMIT_FLAG_ROTATION_SCALE = 2,
+ PARTICLES_EMIT_FLAG_VELOCITY = 4,
+ PARTICLES_EMIT_FLAG_COLOR = 8,
+ PARTICLES_EMIT_FLAG_CUSTOM = 16
+ };
+
+ virtual void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) = 0;
+
enum ParticlesDrawOrder {
PARTICLES_DRAW_ORDER_INDEX,
PARTICLES_DRAW_ORDER_LIFETIME,
@@ -784,6 +797,7 @@ public:
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
+ virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR,
@@ -871,7 +885,7 @@ public:
ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH,
};
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
@@ -1298,6 +1312,8 @@ public:
virtual bool is_low_end() const = 0;
+ RenderingDevice *create_local_rendering_device() const;
+
bool is_render_loop_enabled() const;
void set_render_loop_enabled(bool p_enabled);
diff --git a/servers/text_server.h b/servers/text_server.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/servers/text_server.h
diff --git a/tests/SCsub b/tests/SCsub
index 84c9fc1ffe..7aab28531d 100644
--- a/tests/SCsub
+++ b/tests/SCsub
@@ -6,8 +6,9 @@ env.tests_sources = []
env_tests = env.Clone()
-# Enable test framework and inform it of configuration method.
-env_tests.Append(CPPDEFINES=["DOCTEST_CONFIG_IMPLEMENT"])
+# Include GDNative headers.
+if env["module_gdnative_enabled"]:
+ env_tests.Append(CPPPATH=["#modules/gdnative/include"])
# We must disable the THREAD_LOCAL entirely in doctest to prevent crashes on debugging
# Since we link with /MT thread_local is always expired when the header is used
diff --git a/tests/test_color.h b/tests/test_color.h
index 3633f2746d..dfdc29ec7d 100644
--- a/tests/test_color.h
+++ b/tests/test_color.h
@@ -39,9 +39,7 @@ namespace TestColor {
TEST_CASE("[Color] Constructor methods") {
const Color blue_rgba = Color(0.25098, 0.376471, 1, 0.501961);
- // HTML currently uses ARGB notation, which is contrary to the CSS standard.
- // This may be changed to RGBA in 4.0.
- const Color blue_html = Color::html("#804060ff");
+ const Color blue_html = Color::html("#4060ff80");
const Color blue_hex = Color::hex(0x4060ff80);
const Color blue_hex64 = Color::hex64(0x4040'6060'ffff'8080);
@@ -118,10 +116,10 @@ TEST_CASE("[Color] Conversion methods") {
const Color cyan_transparent = Color(0, 1, 1, 0);
CHECK_MESSAGE(
- cyan.to_html() == "ff00ffff",
+ cyan.to_html() == "00ffffff",
"The returned RGB HTML color code should match the expected value.");
CHECK_MESSAGE(
- cyan_transparent.to_html() == "0000ffff",
+ cyan_transparent.to_html() == "00ffff00",
"The returned RGBA HTML color code should match the expected value.");
CHECK_MESSAGE(
cyan.to_argb32() == 0xff00ffff,
diff --git a/tests/test_expression.h b/tests/test_expression.h
new file mode 100644
index 0000000000..a3d4877d52
--- /dev/null
+++ b/tests/test_expression.h
@@ -0,0 +1,445 @@
+/*************************************************************************/
+/* test_expression.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_EXPRESSION_H
+#define TEST_EXPRESSION_H
+
+#include "core/math/expression.h"
+
+#include "tests/test_macros.h"
+
+namespace TestExpression {
+
+TEST_CASE("[Expression] Integer arithmetic") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("-123456") == OK,
+ "Integer identity should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == -123456,
+ "Integer identity should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("2 + 3") == OK,
+ "Integer addition should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 5,
+ "Integer addition should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("999999999999 + 999999999999") == OK,
+ "Large integer addition should parse successfully.");
+ CHECK_MESSAGE(
+ int64_t(expression.execute()) == 1'999'999'999'998,
+ "Large integer addition should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("25 / 10") == OK,
+ "Integer / integer division should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 2,
+ "Integer / integer division should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("2 * (6 + 14) / 2 - 5") == OK,
+ "Integer multiplication-addition-subtraction-division should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 15,
+ "Integer multiplication-addition-subtraction-division should return the expected result.");
+}
+
+TEST_CASE("[Expression] Floating-point arithmetic") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("-123.456") == OK,
+ "Float identity should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), -123.456),
+ "Float identity should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("2.0 + 3.0") == OK,
+ "Float addition should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 5),
+ "Float addition should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("3.0 / 10") == OK,
+ "Float / integer division should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 0.3),
+ "Float / integer division should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("3 / 10.0") == OK,
+ "Basic integer / float division should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 0.3),
+ "Basic integer / float division should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("3.0 / 10.0") == OK,
+ "Float / float division should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 0.3),
+ "Float / float division should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("2.5 * (6.0 + 14.25) / 2.0 - 5.12345") == OK,
+ "Float multiplication-addition-subtraction-division should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 20.18905),
+ "Float multiplication-addition-subtraction-division should return the expected result.");
+}
+
+TEST_CASE("[Expression] Scientific notation") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("2.e5") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 200'000),
+ "The expression should return the expected result.");
+
+ // The middle "e" is ignored here.
+ CHECK_MESSAGE(
+ expression.parse("2e5") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 25),
+ "The expression should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("2e.5") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 2),
+ "The expression should return the expected result.");
+}
+
+TEST_CASE("[Expression] Underscored numeric literals") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("1_000_000") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ expression.parse("1_000.000") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ expression.parse("0xff_99_00") == OK,
+ "The expression should parse successfully.");
+}
+
+TEST_CASE("[Expression] Built-in functions") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("sqrt(pow(3, 2) + pow(4, 2))") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 5,
+ "`sqrt(pow(3, 2) + pow(4, 2))` should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("stepify(sin(0.5), 0.01)") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(float(expression.execute()), 0.48),
+ "`stepify(sin(0.5), 0.01)` should return the expected result.");
+
+ CHECK_MESSAGE(
+ expression.parse("pow(2.0, -2500)") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_zero_approx(float(expression.execute())),
+ "`pow(2.0, -2500)` should return the expected result (asymptotically zero).");
+}
+
+TEST_CASE("[Expression] Boolean expressions") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("24 >= 12") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ bool(expression.execute()),
+ "The boolean expression should evaluate to `true`.");
+
+ CHECK_MESSAGE(
+ expression.parse("1.0 < 1.25 && 1.25 < 2.0") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ bool(expression.execute()),
+ "The boolean expression should evaluate to `true`.");
+
+ CHECK_MESSAGE(
+ expression.parse("!2") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ !bool(expression.execute()),
+ "The boolean expression should evaluate to `false`.");
+
+ CHECK_MESSAGE(
+ expression.parse("!!2") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ bool(expression.execute()),
+ "The boolean expression should evaluate to `true`.");
+
+ CHECK_MESSAGE(
+ expression.parse("!0") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ bool(expression.execute()),
+ "The boolean expression should evaluate to `true`.");
+
+ CHECK_MESSAGE(
+ expression.parse("!!0") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ !bool(expression.execute()),
+ "The boolean expression should evaluate to `false`.");
+
+ CHECK_MESSAGE(
+ expression.parse("2 && 5") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ bool(expression.execute()),
+ "The boolean expression should evaluate to `true`.");
+
+ CHECK_MESSAGE(
+ expression.parse("0 || 0") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ !bool(expression.execute()),
+ "The boolean expression should evaluate to `false`.");
+
+ CHECK_MESSAGE(
+ expression.parse("(2 <= 4) && (2 > 5)") == OK,
+ "The boolean expression should parse successfully.");
+ CHECK_MESSAGE(
+ !bool(expression.execute()),
+ "The boolean expression should evaluate to `false`.");
+}
+
+TEST_CASE("[Expression] Expressions with variables") {
+ Expression expression;
+
+ PackedStringArray parameter_names;
+ parameter_names.push_back("foo");
+ parameter_names.push_back("bar");
+ CHECK_MESSAGE(
+ expression.parse("foo + bar + 50", parameter_names) == OK,
+ "The expression should parse successfully.");
+ Array values;
+ values.push_back(60);
+ values.push_back(20);
+ CHECK_MESSAGE(
+ int(expression.execute(values)) == 130,
+ "The expression should return the expected value.");
+
+ PackedStringArray parameter_names_invalid;
+ parameter_names_invalid.push_back("foo");
+ parameter_names_invalid.push_back("baz"); // Invalid parameter name.
+ CHECK_MESSAGE(
+ expression.parse("foo + bar + 50", parameter_names_invalid) == OK,
+ "The expression should parse successfully.");
+ Array values_invalid;
+ values_invalid.push_back(60);
+ values_invalid.push_back(20);
+ // Invalid parameters will parse successfully but print an error message when executing.
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ int(expression.execute(values_invalid)) == 0,
+ "The expression should return the expected value.");
+ ERR_PRINT_ON;
+
+ // Mismatched argument count (more values than parameters).
+ PackedStringArray parameter_names_mismatch;
+ parameter_names_mismatch.push_back("foo");
+ parameter_names_mismatch.push_back("bar");
+ CHECK_MESSAGE(
+ expression.parse("foo + bar + 50", parameter_names_mismatch) == OK,
+ "The expression should parse successfully.");
+ Array values_mismatch;
+ values_mismatch.push_back(60);
+ values_mismatch.push_back(20);
+ values_mismatch.push_back(110);
+ CHECK_MESSAGE(
+ int(expression.execute(values_mismatch)) == 130,
+ "The expression should return the expected value.");
+
+ // Mismatched argument count (more parameters than values).
+ PackedStringArray parameter_names_mismatch2;
+ parameter_names_mismatch2.push_back("foo");
+ parameter_names_mismatch2.push_back("bar");
+ parameter_names_mismatch2.push_back("baz");
+ CHECK_MESSAGE(
+ expression.parse("foo + bar + baz + 50", parameter_names_mismatch2) == OK,
+ "The expression should parse successfully.");
+ Array values_mismatch2;
+ values_mismatch2.push_back(60);
+ values_mismatch2.push_back(20);
+ // Having more parameters than values will parse successfully but print an
+ // error message when executing.
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ int(expression.execute(values_mismatch2)) == 0,
+ "The expression should return the expected value.");
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[Expression] Invalid expressions") {
+ Expression expression;
+
+ CHECK_MESSAGE(
+ expression.parse("\\") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("0++") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("()") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("()()") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("() - ()") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("() * 12345") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("() * 12345") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("123'456") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+
+ CHECK_MESSAGE(
+ expression.parse("123\"456") == ERR_INVALID_PARAMETER,
+ "The expression shouldn't parse successfully.");
+}
+
+TEST_CASE("[Expression] Unusual expressions") {
+ Expression expression;
+
+ // Redundant parentheses don't cause a parse error as long as they're matched.
+ CHECK_MESSAGE(
+ expression.parse("(((((((((((((((666)))))))))))))))") == OK,
+ "The expression should parse successfully.");
+
+ // Using invalid identifiers doesn't cause a parse error.
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ expression.parse("hello + hello") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 0,
+ "The expression should return the expected result.");
+ ERR_PRINT_ON;
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ expression.parse("$1.00 + €5") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 0,
+ "The expression should return the expected result.");
+ ERR_PRINT_ON;
+
+ // Commas can't be used as a decimal parameter.
+ CHECK_MESSAGE(
+ expression.parse("123,456") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 123,
+ "The expression should return the expected result.");
+
+ // Spaces can't be used as a separator for large numbers.
+ CHECK_MESSAGE(
+ expression.parse("123 456") == OK,
+ "The expression should parse successfully.");
+ CHECK_MESSAGE(
+ int(expression.execute()) == 123,
+ "The expression should return the expected result.");
+
+ // Division by zero is accepted, even though it prints an error message normally.
+ CHECK_MESSAGE(
+ expression.parse("-25.4 / 0") == OK,
+ "The expression should parse successfully.");
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ Math::is_zero_approx(float(expression.execute())),
+ "`-25.4 / 0` should return 0.");
+ ERR_PRINT_ON;
+
+ CHECK_MESSAGE(
+ expression.parse("0 / 0") == OK,
+ "The expression should parse successfully.");
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ int(expression.execute()) == 0,
+ "`0 / 0` should return 0.");
+ ERR_PRINT_ON;
+
+ // The tests below currently crash the engine.
+ //
+ //CHECK_MESSAGE(
+ // expression.parse("(-9223372036854775807 - 1) % -1") == OK,
+ // "The expression should parse successfully.");
+ //CHECK_MESSAGE(
+ // int64_t(expression.execute()) == 0,
+ // "`(-9223372036854775807 - 1) % -1` should return the expected result.");
+ //
+ //CHECK_MESSAGE(
+ // expression.parse("(-9223372036854775807 - 1) / -1") == OK,
+ // "The expression should parse successfully.");
+ //CHECK_MESSAGE(
+ // int64_t(expression.execute()) == 0,
+ // "`(-9223372036854775807 - 1) / -1` should return the expected result.");
+}
+
+} // namespace TestExpression
+
+#endif // TEST_EXPRESSION_H
diff --git a/tests/test_list.h b/tests/test_list.h
new file mode 100644
index 0000000000..7412fbc3c8
--- /dev/null
+++ b/tests/test_list.h
@@ -0,0 +1,279 @@
+/*************************************************************************/
+/* test_list.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_LIST_H
+#define TEST_LIST_H
+
+#include "core/list.h"
+
+#include "tests/test_macros.h"
+
+namespace TestList {
+
+static void populate_integers(List<int> &p_list, List<int>::Element *r_elements[], int num_elements) {
+ p_list.clear();
+ for (int i = 0; i < num_elements; ++i) {
+ List<int>::Element *n = p_list.push_back(i);
+ r_elements[i] = n;
+ }
+}
+
+TEST_CASE("[List] Swap adjacent front and back") {
+ List<int> list;
+ List<int>::Element *n[2];
+ populate_integers(list, n, 2);
+
+ list.swap(list.front(), list.back());
+
+ CHECK(list.front()->prev() == nullptr);
+ CHECK(list.front() != list.front()->next());
+
+ CHECK(list.front() == n[1]);
+ CHECK(list.back() == n[0]);
+
+ CHECK(list.back()->next() == nullptr);
+ CHECK(list.back() != list.back()->prev());
+}
+
+TEST_CASE("[List] Swap first adjacent pair") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[0], n[1]);
+
+ CHECK(list.front()->prev() == nullptr);
+ CHECK(list.front() != list.front()->next());
+
+ CHECK(list.front() == n[1]);
+ CHECK(list.front()->next() == n[0]);
+ CHECK(list.back()->prev() == n[2]);
+ CHECK(list.back() == n[3]);
+
+ CHECK(list.back()->next() == nullptr);
+ CHECK(list.back() != list.back()->prev());
+}
+
+TEST_CASE("[List] Swap middle adjacent pair") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[1], n[2]);
+
+ CHECK(list.front()->prev() == nullptr);
+
+ CHECK(list.front() == n[0]);
+ CHECK(list.front()->next() == n[2]);
+ CHECK(list.back()->prev() == n[1]);
+ CHECK(list.back() == n[3]);
+
+ CHECK(list.back()->next() == nullptr);
+}
+
+TEST_CASE("[List] Swap last adjacent pair") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[2], n[3]);
+
+ CHECK(list.front()->prev() == nullptr);
+
+ CHECK(list.front() == n[0]);
+ CHECK(list.front()->next() == n[1]);
+ CHECK(list.back()->prev() == n[3]);
+ CHECK(list.back() == n[2]);
+
+ CHECK(list.back()->next() == nullptr);
+}
+
+TEST_CASE("[List] Swap first cross pair") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[0], n[2]);
+
+ CHECK(list.front()->prev() == nullptr);
+
+ CHECK(list.front() == n[2]);
+ CHECK(list.front()->next() == n[1]);
+ CHECK(list.back()->prev() == n[0]);
+ CHECK(list.back() == n[3]);
+
+ CHECK(list.back()->next() == nullptr);
+}
+
+TEST_CASE("[List] Swap last cross pair") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[1], n[3]);
+
+ CHECK(list.front()->prev() == nullptr);
+
+ CHECK(list.front() == n[0]);
+ CHECK(list.front()->next() == n[3]);
+ CHECK(list.back()->prev() == n[2]);
+ CHECK(list.back() == n[1]);
+
+ CHECK(list.back()->next() == nullptr);
+}
+
+TEST_CASE("[List] Swap edges") {
+ List<int> list;
+ List<int>::Element *n[4];
+ populate_integers(list, n, 4);
+
+ list.swap(n[1], n[3]);
+
+ CHECK(list.front()->prev() == nullptr);
+
+ CHECK(list.front() == n[0]);
+ CHECK(list.front()->next() == n[3]);
+ CHECK(list.back()->prev() == n[2]);
+ CHECK(list.back() == n[1]);
+
+ CHECK(list.back()->next() == nullptr);
+}
+
+TEST_CASE("[List] Swap middle (values check)") {
+ List<String> list;
+ List<String>::Element *n_str1 = list.push_back("Still");
+ List<String>::Element *n_str2 = list.push_back("waiting");
+ List<String>::Element *n_str3 = list.push_back("for");
+ List<String>::Element *n_str4 = list.push_back("Godot.");
+
+ CHECK(n_str1->get() == "Still");
+ CHECK(n_str4->get() == "Godot.");
+
+ CHECK(list.front()->get() == "Still");
+ CHECK(list.front()->next()->get() == "waiting");
+ CHECK(list.back()->prev()->get() == "for");
+ CHECK(list.back()->get() == "Godot.");
+
+ list.swap(n_str2, n_str3);
+
+ CHECK(list.front()->next()->get() == "for");
+ CHECK(list.back()->prev()->get() == "waiting");
+}
+
+TEST_CASE("[List] Swap front and back (values check)") {
+ List<Variant> list;
+ Variant str = "Godot";
+ List<Variant>::Element *n_str = list.push_back(str);
+ Variant color = Color(0, 0, 1);
+ List<Variant>::Element *n_color = list.push_back(color);
+
+ CHECK(list.front()->get() == "Godot");
+ CHECK(list.back()->get() == Color(0, 0, 1));
+
+ list.swap(n_str, n_color);
+
+ CHECK(list.front()->get() == Color(0, 0, 1));
+ CHECK(list.back()->get() == "Godot");
+}
+
+TEST_CASE("[List] Swap adjacent back and front (reverse order of elements)") {
+ List<int> list;
+ List<int>::Element *n[2];
+ populate_integers(list, n, 2);
+
+ list.swap(n[1], n[0]);
+
+ List<int>::Element *it = list.front();
+ while (it) {
+ List<int>::Element *prev_it = it;
+ it = it->next();
+ if (it == prev_it) {
+ FAIL_CHECK("Infinite loop detected.");
+ break;
+ }
+ }
+}
+
+static void swap_random(List<int> &p_list, List<int>::Element *r_elements[], size_t p_size, size_t p_iterations) {
+ Math::seed(0);
+
+ for (size_t test_i = 0; test_i < p_iterations; ++test_i) {
+ // A and B elements have corresponding indices as values.
+ const int a_idx = static_cast<int>(Math::rand() % p_size);
+ const int b_idx = static_cast<int>(Math::rand() % p_size);
+ List<int>::Element *a = p_list.find(a_idx); // via find.
+ List<int>::Element *b = r_elements[b_idx]; // via pointer.
+
+ int va = a->get();
+ int vb = b->get();
+
+ p_list.swap(a, b);
+
+ CHECK(va == a->get());
+ CHECK(vb == b->get());
+
+ size_t element_count = 0;
+
+ // Fully traversable after swap?
+ List<int>::Element *it = p_list.front();
+ while (it) {
+ element_count += 1;
+ List<int>::Element *prev_it = it;
+ it = it->next();
+ if (it == prev_it) {
+ FAIL_CHECK("Infinite loop detected.");
+ break;
+ }
+ }
+ // We should not lose anything in the process.
+ if (element_count != p_size) {
+ FAIL_CHECK("Element count mismatch.");
+ break;
+ }
+ }
+}
+
+TEST_CASE("[Stress][List] Swap random 100 elements, 500 iterations.") {
+ List<int> list;
+ List<int>::Element *n[100];
+ populate_integers(list, n, 100);
+ swap_random(list, n, 100, 500);
+}
+
+TEST_CASE("[Stress][List] Swap random 10 elements, 1000 iterations.") {
+ List<int> list;
+ List<int>::Element *n[10];
+ populate_integers(list, n, 10);
+ swap_random(list, n, 10, 1000);
+}
+
+} // namespace TestList
+
+#endif // TEST_LIST_H
diff --git a/tests/test_macros.cpp b/tests/test_macros.cpp
new file mode 100644
index 0000000000..2317223b23
--- /dev/null
+++ b/tests/test_macros.cpp
@@ -0,0 +1,42 @@
+/*************************************************************************/
+/* test_macros.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#define DOCTEST_CONFIG_IMPLEMENT
+#include "test_macros.h"
+
+Map<String, TestFunc> *test_commands = nullptr;
+
+int register_test_command(String p_command, TestFunc p_function) {
+ if (!test_commands) {
+ test_commands = new Map<String, TestFunc>;
+ }
+ test_commands->insert(p_command, p_function);
+ return 0;
+}
diff --git a/tests/test_macros.h b/tests/test_macros.h
index 45ba8581dd..3486c68bb7 100644
--- a/tests/test_macros.h
+++ b/tests/test_macros.h
@@ -31,6 +31,9 @@
#ifndef TEST_MACROS_H
#define TEST_MACROS_H
+#include "core/map.h"
+#include "core/variant.h"
+
// See documentation for doctest at:
// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md#reference
#include "thirdparty/doctest/doctest.h"
@@ -104,4 +107,17 @@ DOCTEST_STRINGIFY_VARIANT(PackedVector2Array);
DOCTEST_STRINGIFY_VARIANT(PackedVector3Array);
DOCTEST_STRINGIFY_VARIANT(PackedColorArray);
+// Register test commands to be launched from the command-line.
+// For instance: REGISTER_TEST_COMMAND("gdscript-parser" &test_parser_func).
+// Example usage: `godot --test gdscript-parser`.
+
+typedef void (*TestFunc)();
+extern Map<String, TestFunc> *test_commands;
+int register_test_command(String p_command, TestFunc p_function);
+
+#define REGISTER_TEST_COMMAND(m_command, m_function) \
+ DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \
+ register_test_command(m_command, m_function); \
+ DOCTEST_GLOBAL_NO_WARNINGS_END()
+
#endif // TEST_MACROS_H
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 892cc26a51..f0dec22738 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -36,9 +36,10 @@
#include "test_basis.h"
#include "test_class_db.h"
#include "test_color.h"
-#include "test_gdscript.h"
+#include "test_expression.h"
#include "test_gradient.h"
#include "test_gui.h"
+#include "test_list.h"
#include "test_math.h"
#include "test_oa_hash_map.h"
#include "test_ordered_hash_map.h"
@@ -55,40 +56,64 @@
#include "tests/test_macros.h"
int test_main(int argc, char *argv[]) {
+ bool run_tests = true;
+
+ // Convert arguments to Godot's command-line.
+ List<String> args;
+
+ for (int i = 0; i < argc; i++) {
+ args.push_back(String::utf8(argv[i]));
+ }
+ OS::get_singleton()->set_cmdline("", args);
+
+ // Run custom test tools.
+ if (test_commands) {
+ for (Map<String, TestFunc>::Element *E = test_commands->front(); E; E = E->next()) {
+ if (args.find(E->key())) {
+ const TestFunc &test_func = E->get();
+ test_func();
+ run_tests = false;
+ break;
+ }
+ }
+ if (!run_tests) {
+ delete test_commands;
+ return 0;
+ }
+ }
// Doctest runner.
doctest::Context test_context;
- List<String> valid_arguments;
+ List<String> test_args;
// Clean arguments of "--test" from the args.
- int argument_count = 0;
for (int x = 0; x < argc; x++) {
- if (strncmp(argv[x], "--test", 6) != 0) {
- valid_arguments.push_back(String(argv[x]));
- argument_count++;
+ String arg = String(argv[x]);
+ if (arg != "--test") {
+ test_args.push_back(arg);
}
}
// Convert Godot command line arguments back to standard arguments.
- char **args = new char *[valid_arguments.size()];
- for (int x = 0; x < valid_arguments.size(); x++) {
+ char **doctest_args = new char *[test_args.size()];
+ for (int x = 0; x < test_args.size(); x++) {
// Operation to convert Godot string to non wchar string.
- CharString cs = valid_arguments[x].utf8();
+ CharString cs = test_args[x].utf8();
const char *str = cs.get_data();
// Allocate the string copy.
- args[x] = new char[strlen(str) + 1];
+ doctest_args[x] = new char[strlen(str) + 1];
// Copy this into memory.
- std::memcpy(args[x], str, strlen(str) + 1);
+ memcpy(doctest_args[x], str, strlen(str) + 1);
}
- test_context.applyCommandLine(valid_arguments.size(), args);
+ test_context.applyCommandLine(test_args.size(), doctest_args);
test_context.setOption("order-by", "name");
test_context.setOption("abort-after", 5);
test_context.setOption("no-breaks", true);
- for (int x = 0; x < valid_arguments.size(); x++) {
- delete[] args[x];
+ for (int x = 0; x < test_args.size(); x++) {
+ delete[] doctest_args[x];
}
- delete[] args;
+ delete[] doctest_args;
return test_context.run();
}
diff --git a/tests/test_math.cpp b/tests/test_math.cpp
index 84a85be2f6..862535b57e 100644
--- a/tests/test_math.cpp
+++ b/tests/test_math.cpp
@@ -162,7 +162,7 @@ class GetClassAndNamespace {
} break;
case '\'':
case '"': {
- CharType begin_str = code[idx];
+ char32_t begin_str = code[idx];
idx++;
String tk_string = String();
while (true) {
@@ -176,13 +176,13 @@ class GetClassAndNamespace {
} else if (code[idx] == '\\') {
//escaped characters...
idx++;
- CharType next = code[idx];
+ char32_t next = code[idx];
if (next == 0) {
error_str = "Unterminated String";
error = true;
return TK_ERROR;
}
- CharType res = 0;
+ char32_t res = 0;
switch (next) {
case 'b':
@@ -241,7 +241,7 @@ class GetClassAndNamespace {
if (code[idx] == '-' || (code[idx] >= '0' && code[idx] <= '9')) {
//a number
- const CharType *rptr;
+ const char32_t *rptr;
double number = String::to_float(&code[idx], &rptr);
idx += (rptr - &code[idx]);
value = number;
diff --git a/tests/test_shader_lang.cpp b/tests/test_shader_lang.cpp
index 34ee3e3210..d363ee22b5 100644
--- a/tests/test_shader_lang.cpp
+++ b/tests/test_shader_lang.cpp
@@ -325,7 +325,7 @@ MainLoop *test() {
String code;
while (true) {
- CharType c = fa->get_8();
+ char32_t c = fa->get_8();
if (fa->eof_reached()) {
break;
}
diff --git a/tests/test_string.h b/tests/test_string.h
index 22019a64c6..b041cb2f49 100644
--- a/tests/test_string.h
+++ b/tests/test_string.h
@@ -48,36 +48,159 @@
namespace TestString {
-TEST_CASE("[String] Assign from cstr") {
+int u32scmp(const char32_t *l, const char32_t *r) {
+ for (; *l == *r && *l && *r; l++, r++)
+ ;
+ return *l - *r;
+}
+
+TEST_CASE("[String] Assign Latin-1 char string") {
String s = "Hello";
- CHECK(wcscmp(s.c_str(), L"Hello") == 0);
+ CHECK(u32scmp(s.get_data(), U"Hello") == 0);
}
-TEST_CASE("[String] Assign from string (operator=)") {
+TEST_CASE("[String] Assign from Latin-1 char string (operator=)") {
String s = "Dolly";
const String &t = s;
- CHECK(wcscmp(t.c_str(), L"Dolly") == 0);
+ CHECK(u32scmp(t.get_data(), U"Dolly") == 0);
}
-TEST_CASE("[String] Assign from c-string (copycon)") {
+TEST_CASE("[String] Assign from Latin-1 char string (copycon)") {
String s("Sheep");
- const String &t(s);
- CHECK(wcscmp(t.c_str(), L"Sheep") == 0);
+ const String &t1(s);
+ CHECK(u32scmp(t1.get_data(), U"Sheep") == 0);
+
+ String t2 = String("Sheep", 3);
+ CHECK(u32scmp(t2.get_data(), U"She") == 0);
}
-TEST_CASE("[String] Assign from c-widechar (operator=)") {
- String s(L"Give me");
- CHECK(wcscmp(s.c_str(), L"Give me") == 0);
+TEST_CASE("[String] Assign from wchar_t string (operator=)") {
+ String s = L"Give me";
+ CHECK(u32scmp(s.get_data(), U"Give me") == 0);
}
-TEST_CASE("[String] Assign from c-widechar (copycon)") {
+TEST_CASE("[String] Assign from wchar_t string (copycon)") {
String s(L"Wool");
- CHECK(wcscmp(s.c_str(), L"Wool") == 0);
+ CHECK(u32scmp(s.get_data(), U"Wool") == 0);
+}
+
+TEST_CASE("[String] Assign from char32_t string (operator=)") {
+ String s = U"Give me";
+ CHECK(u32scmp(s.get_data(), U"Give me") == 0);
+}
+
+TEST_CASE("[String] Assign from char32_t string (copycon)") {
+ String s(U"Wool");
+ CHECK(u32scmp(s.get_data(), U"Wool") == 0);
+}
+
+TEST_CASE("[String] UTF8") {
+ /* how can i embed UTF in here? */
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+ String s = u32str;
+ bool err = s.parse_utf8(s.utf8().get_data());
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ err = s.parse_utf8((const char *)u8str);
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ CharString cs = (const char *)u8str;
+ CHECK(String::utf8(cs) == s);
+}
+
+TEST_CASE("[String] UTF16") {
+ /* how can i embed UTF in here? */
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char16_t u16str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
+ String s = u32str;
+ bool err = s.parse_utf16(s.utf16().get_data());
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ err = s.parse_utf16(u16str);
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ Char16String cs = u16str;
+ CHECK(String::utf16(cs) == s);
+}
+
+TEST_CASE("[String] UTF8 with BOM") {
+ /* how can i embed UTF in here? */
+ static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+ String s;
+ bool err = s.parse_utf8((const char *)u8str);
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ CharString cs = (const char *)u8str;
+ CHECK(String::utf8(cs) == s);
+}
+
+TEST_CASE("[String] UTF16 with BOM") {
+ /* how can i embed UTF in here? */
+ static const char32_t u32str[] = { 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
+ static const char16_t u16str[] = { 0xFEFF, 0x0020, 0x0045, 0x304A, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
+ static const char16_t u16str_swap[] = { 0xFFFE, 0x2000, 0x4500, 0x4A30, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
+ String s;
+ bool err = s.parse_utf16(u16str);
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ err = s.parse_utf16(u16str_swap);
+ CHECK(!err);
+ CHECK(s == u32str);
+
+ Char16String cs = u16str;
+ CHECK(String::utf16(cs) == s);
+
+ cs = u16str_swap;
+ CHECK(String::utf16(cs) == s);
+}
+
+TEST_CASE("[String] Invalid UTF8") {
+ ERR_PRINT_OFF
+ static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
+ String s;
+ bool err = s.parse_utf8((const char *)u8str);
+ CHECK(err);
+ CHECK(s == String());
+
+ CharString cs = (const char *)u8str;
+ CHECK(String::utf8(cs) == String());
+ ERR_PRINT_ON
+}
+
+TEST_CASE("[String] Invalid UTF16") {
+ ERR_PRINT_OFF
+ static const char16_t u16str[] = { 0x0045, 0x304A, 0x3088, 0x3046, 0xDFA4, 0 };
+ String s;
+ bool err = s.parse_utf16(u16str);
+ CHECK(err);
+ CHECK(s == String());
+
+ Char16String cs = u16str;
+ CHECK(String::utf16(cs) == String());
+ ERR_PRINT_ON
+}
+
+TEST_CASE("[String] ASCII") {
+ String s = U"Primero Leche";
+ String t = s.ascii(false).get_data();
+ CHECK(s == t);
+
+ t = s.ascii(true).get_data();
+ CHECK(s == t);
}
TEST_CASE("[String] Comparisons (equal)") {
String s = "Test Compare";
CHECK(s == "Test Compare");
+ CHECK(s == U"Test Compare");
CHECK(s == L"Test Compare");
CHECK(s == String("Test Compare"));
}
@@ -85,6 +208,7 @@ TEST_CASE("[String] Comparisons (equal)") {
TEST_CASE("[String] Comparisons (not equal)") {
String s = "Test Compare";
CHECK(s != "Peanut");
+ CHECK(s != U"Coconut");
CHECK(s != L"Coconut");
CHECK(s != String("Butter"));
}
@@ -92,6 +216,7 @@ TEST_CASE("[String] Comparisons (not equal)") {
TEST_CASE("[String] Comparisons (operator <)") {
String s = "Bees";
CHECK(s < "Elephant");
+ CHECK(!(s < U"Amber"));
CHECK(!(s < L"Amber"));
CHECK(!(s < String("Beatrix")));
}
@@ -103,7 +228,7 @@ TEST_CASE("[String] Concatenation") {
s += ' ';
s += 'a';
s += String(" ");
- s = s + L"Nice";
+ s = s + U"Nice";
s = s + " ";
s = s + String("Day");
@@ -130,34 +255,49 @@ TEST_CASE("[String] Testing for empty string") {
CHECK(String("").empty());
}
+TEST_CASE("[String] Test chr") {
+ CHECK(String::chr('H') == "H");
+ CHECK(String::chr(0x3012)[0] == 0x3012);
+ ERR_PRINT_OFF
+ CHECK(String::chr(0xd812)[0] == 0xfffd); // Unpaired UTF-16 surrogate
+ CHECK(String::chr(0x20d812)[0] == 0xfffd); // Outside UTF-32 range
+ ERR_PRINT_ON
+}
+
TEST_CASE("[String] Operator []") {
String a = "Kugar Sane";
a[0] = 'S';
a[6] = 'C';
CHECK(a == "Sugar Cane");
CHECK(a[1] == 'u');
+ CHECK(a.ord_at(1) == 'u');
}
TEST_CASE("[String] Case function test") {
String a = "MoMoNgA";
CHECK(a.to_upper() == "MOMONGA");
+ CHECK(a.to_lower() == "momonga");
+}
+
+TEST_CASE("[String] Case compare function test") {
+ String a = "MoMoNgA";
+
+ CHECK(a.casecmp_to("momonga") != 0);
CHECK(a.nocasecmp_to("momonga") == 0);
}
-TEST_CASE("[String] UTF8") {
- /* how can i embed UTF in here? */
- static const CharType ustr[] = { 0x304A, 0x360F, 0x3088, 0x3046, 0 };
- //static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
- String s = ustr;
- s.parse_utf8(s.utf8().get_data());
- CHECK(s == ustr);
+TEST_CASE("[String] Natural compare function test") {
+ String a = "img2.png";
+
+ CHECK(a.nocasecmp_to("img10.png") > 0);
+ CHECK(a.naturalnocasecmp_to("img10.png") < 0);
}
-TEST_CASE("[String] ASCII") {
- String s = L"Primero Leche";
- String t = s.ascii().get_data();
- CHECK(s == t);
+TEST_CASE("[String] hex_encode_buffer") {
+ static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3 };
+ String s = String::hex_encode_buffer(u8str, 6);
+ CHECK(s == U"45e3818a8fe3");
}
TEST_CASE("[String] Substr") {
@@ -165,24 +305,45 @@ TEST_CASE("[String] Substr") {
CHECK(s.substr(3, 4) == "ler ");
}
-TEST_CASE("[string] Find") {
- String s = "Pretty Woman";
- s.find("Revenge of the Monster Truck");
-
+TEST_CASE("[String] Find") {
+ String s = "Pretty Woman Woman";
CHECK(s.find("tty") == 3);
+ CHECK(s.find("Wo", 9) == 13);
CHECK(s.find("Revenge of the Monster Truck") == -1);
+ CHECK(s.rfind("man") == 15);
}
-TEST_CASE("[String] find no case") {
- String s = "Pretty Whale";
+TEST_CASE("[String] Find no case") {
+ String s = "Pretty Whale Whale";
CHECK(s.findn("WHA") == 7);
+ CHECK(s.findn("WHA", 9) == 13);
CHECK(s.findn("Revenge of the Monster SawFish") == -1);
+ CHECK(s.rfindn("WHA") == 13);
+}
+
+TEST_CASE("[String] Find MK") {
+ Vector<String> keys;
+ keys.push_back("sty");
+ keys.push_back("tty");
+ keys.push_back("man");
+
+ String s = "Pretty Woman";
+ int key = 0;
+
+ CHECK(s.findmk(keys, 0, &key) == 3);
+ CHECK(key == 1);
+
+ CHECK(s.findmk(keys, 5, &key) == 9);
+ CHECK(key == 2);
}
TEST_CASE("[String] Find and replace") {
String s = "Happy Birthday, Anna!";
s = s.replace("Birthday", "Halloween");
CHECK(s == "Happy Halloween, Anna!");
+
+ s = s.replace_first("H", "W");
+ CHECK(s == "Wappy Halloween, Anna!");
}
TEST_CASE("[String] Insertion") {
@@ -193,6 +354,12 @@ TEST_CASE("[String] Insertion") {
TEST_CASE("[String] Number to string") {
CHECK(String::num(3.141593) == "3.141593");
+ CHECK(String::num(3.141593, 3) == "3.142");
+ CHECK(String::num_real(3.141593) == "3.141593");
+ CHECK(String::num_scientific(30000000) == "3e+07");
+ CHECK(String::num_int64(3141593) == "3141593");
+ CHECK(String::num_int64(0xA141593, 16) == "a141593");
+ CHECK(String::num_int64(0xA141593, 16, true) == "A141593");
}
TEST_CASE("[String] String to integer") {
@@ -204,6 +371,18 @@ TEST_CASE("[String] String to integer") {
}
}
+TEST_CASE("[String] Hex to integer") {
+ static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" };
+ static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD };
+ static const bool wo_prefix[4] = { false, true, true, true };
+ static const bool w_prefix[4] = { true, false, true, false };
+
+ for (int i = 0; i < 4; i++) {
+ CHECK((String(nums[i]).hex_to_int(true) == num[i]) == w_prefix[i]);
+ CHECK((String(nums[i]).hex_to_int(false) == num[i]) == wo_prefix[i]);
+ }
+}
+
TEST_CASE("[String] String to float") {
static const char *nums[4] = { "-12348298412.2", "0.05", "2.0002", " -0.0001" };
static const double num[4] = { -12348298412.2, 0.05, 2.0002, -0.0001 };
@@ -213,6 +392,11 @@ TEST_CASE("[String] String to float") {
}
}
+TEST_CASE("[String] CamelCase to underscore") {
+ CHECK(String("TestTestStringGD").camelcase_to_underscore(false) == String("Test_Test_String_GD"));
+ CHECK(String("TestTestStringGD").camelcase_to_underscore(true) == String("test_test_string_gd"));
+}
+
TEST_CASE("[String] Slicing") {
String s = "Mars,Jupiter,Saturn,Uranus";
@@ -222,6 +406,69 @@ TEST_CASE("[String] Slicing") {
}
}
+TEST_CASE("[String] Splitting") {
+ String s = "Mars,Jupiter,Saturn,Uranus";
+ Vector<String> l;
+
+ const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" };
+ const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" };
+
+ l = s.split(",", true, 2);
+ CHECK(l.size() == 3);
+ for (int i = 0; i < l.size(); i++) {
+ CHECK(l[i] == slices_l[i]);
+ }
+
+ l = s.rsplit(",", true, 2);
+ CHECK(l.size() == 3);
+ for (int i = 0; i < l.size(); i++) {
+ CHECK(l[i] == slices_r[i]);
+ }
+
+ s = "Mars Jupiter Saturn Uranus";
+ const char *slices_s[4] = { "Mars", "Jupiter", "Saturn", "Uranus" };
+ l = s.split_spaces();
+ for (int i = 0; i < l.size(); i++) {
+ CHECK(l[i] == slices_s[i]);
+ }
+
+ s = "1.2;2.3 4.5";
+ const double slices_d[3] = { 1.2, 2.3, 4.5 };
+
+ Vector<float> f;
+ f = s.split_floats(";");
+ CHECK(f.size() == 2);
+ for (int i = 0; i < f.size(); i++) {
+ CHECK(ABS(f[i] - slices_d[i]) <= 0.00001);
+ }
+
+ Vector<String> keys;
+ keys.push_back(";");
+ keys.push_back(" ");
+
+ f = s.split_floats_mk(keys);
+ CHECK(f.size() == 3);
+ for (int i = 0; i < f.size(); i++) {
+ CHECK(ABS(f[i] - slices_d[i]) <= 0.00001);
+ }
+
+ s = "1;2 4";
+ const int slices_i[3] = { 1, 2, 4 };
+
+ Vector<int> ii;
+ ii = s.split_ints(";");
+ CHECK(ii.size() == 2);
+ for (int i = 0; i < ii.size(); i++) {
+ CHECK(ii[i] == slices_i[i]);
+ }
+
+ ii = s.split_ints_mk(keys);
+ CHECK(ii.size() == 3);
+ for (int i = 0; i < ii.size(); i++) {
+ CHECK(ii[i] == slices_i[i]);
+ }
+}
+
TEST_CASE("[String] Erasing") {
String s = "Josephine is such a cute girl!";
s.erase(s.find("cute "), String("cute ").length());
@@ -239,7 +486,7 @@ TEST_CASE("[String] Regex substitution") {
struct test_27_data {
char const *data;
- char const *begin;
+ char const *part;
bool expected;
};
@@ -253,9 +500,9 @@ TEST_CASE("[String] Begins with") {
bool state = true;
for (size_t i = 0; state && i < count; ++i) {
String s = tc[i].data;
- state = s.begins_with(tc[i].begin) == tc[i].expected;
+ state = s.begins_with(tc[i].part) == tc[i].expected;
if (state) {
- String sb = tc[i].begin;
+ String sb = tc[i].part;
state = s.begins_with(sb) == tc[i].expected;
}
CHECK(state);
@@ -266,6 +513,42 @@ TEST_CASE("[String] Begins with") {
CHECK(state);
}
+TEST_CASE("[String] Ends with") {
+ test_27_data tc[] = {
+ { "res://foobar", "foobar", true },
+ { "res", "res://", false },
+ { "abc", "abc", true }
+ };
+ size_t count = sizeof(tc) / sizeof(tc[0]);
+ bool state = true;
+ for (size_t i = 0; state && i < count; ++i) {
+ String s = tc[i].data;
+ state = s.ends_with(tc[i].part) == tc[i].expected;
+ if (state) {
+ String sb = tc[i].part;
+ state = s.ends_with(sb) == tc[i].expected;
+ }
+ CHECK(state);
+ if (!state) {
+ break;
+ }
+ };
+ CHECK(state);
+}
+
+TEST_CASE("[String] format") {
+ const String value_format = "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\"";
+
+ Dictionary value_dictionary;
+ value_dictionary["red"] = 10;
+ value_dictionary["green"] = 20;
+ value_dictionary["blue"] = "bla";
+ value_dictionary["alpha"] = 0.4;
+ String value = value_format.format(value_dictionary, "$_");
+
+ CHECK(value == "red=\"10\" green=\"20\" blue=\"bla\" alpha=\"0.4\"");
+}
+
TEST_CASE("[String] sprintf") {
String format, output;
Array args;
@@ -560,6 +843,38 @@ TEST_CASE("[String] sprintf") {
CHECK(output == "%c requires number or single-character string");
}
+TEST_CASE("[String] is_numeric") {
+ CHECK(String("12").is_numeric());
+ CHECK(String("1.2").is_numeric());
+ CHECK(!String("AF").is_numeric());
+ CHECK(String("-12").is_numeric());
+ CHECK(String("-1.2").is_numeric());
+}
+
+TEST_CASE("[String] pad") {
+ String s = String("test");
+ CHECK(s.lpad(10, "x") == U"xxxxxxtest");
+ CHECK(s.rpad(10, "x") == U"testxxxxxx");
+
+ s = String("10.10");
+ CHECK(s.pad_decimals(4) == U"10.1000");
+ CHECK(s.pad_zeros(4) == U"0010.10");
+}
+
+TEST_CASE("[String] is_subsequence_of") {
+ String a = "is subsequence of";
+ CHECK(String("sub").is_subsequence_of(a));
+ CHECK(!String("Sub").is_subsequence_of(a));
+ CHECK(String("Sub").is_subsequence_ofi(a));
+}
+
+TEST_CASE("[String] match") {
+ CHECK(String("img1.png").match("*.png"));
+ CHECK(!String("img1.jpeg").match("*.png"));
+ CHECK(!String("img1.Png").match("*.png"));
+ CHECK(String("img1.Png").matchn("*.png"));
+}
+
TEST_CASE("[String] IPVX address to string") {
IP_Address ip0("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
IP_Address ip(0x0123, 0x4567, 0x89ab, 0xcdef, true);
@@ -792,7 +1107,196 @@ TEST_CASE("[String] Count and countn functionality") {
COUNT_TEST(String("testTest-TeStatest").countn("tEsT", 4, 16) == 2);
CHECK(state);
+
+#undef COUNT_TEST
+}
+
+TEST_CASE("[String] Bigrams") {
+ String s = "abcd";
+ Vector<String> bigr = s.bigrams();
+
+ CHECK(bigr.size() == 3);
+ CHECK(bigr[0] == "ab");
+ CHECK(bigr[1] == "bc");
+ CHECK(bigr[2] == "cd");
+}
+
+TEST_CASE("[String] c-escape/unescape") {
+ String s = "\\1\a2\b\f3\n45\r6\t7\v8\'9\?0\"";
+ CHECK(s.c_escape().c_unescape() == s);
+}
+
+TEST_CASE("[String] dedent") {
+ String s = " aaa\n bbb";
+ String t = "aaa\nbbb";
+ CHECK(s.dedent() == t);
+}
+
+TEST_CASE("[String] Path functions") {
+ static const char *path[4] = { "C:\\Godot\\project\\test.tscn", "/Godot/project/test.xscn", "../Godot/project/test.scn", "Godot\\test.doc" };
+ static const char *base_dir[4] = { "C:\\Godot\\project", "/Godot/project", "../Godot/project", "Godot" };
+ static const char *base_name[4] = { "C:\\Godot\\project\\test", "/Godot/project/test", "../Godot/project/test", "Godot\\test" };
+ static const char *ext[4] = { "tscn", "xscn", "scn", "doc" };
+ static const char *file[4] = { "test.tscn", "test.xscn", "test.scn", "test.doc" };
+ static const bool abs[4] = { true, true, false, false };
+
+ for (int i = 0; i < 4; i++) {
+ CHECK(String(path[i]).get_base_dir() == base_dir[i]);
+ CHECK(String(path[i]).get_basename() == base_name[i]);
+ CHECK(String(path[i]).get_extension() == ext[i]);
+ CHECK(String(path[i]).get_file() == file[i]);
+ CHECK(String(path[i]).is_abs_path() == abs[i]);
+ CHECK(String(path[i]).is_rel_path() != abs[i]);
+ CHECK(String(path[i]).simplify_path().get_base_dir().plus_file(file[i]) == String(path[i]).simplify_path());
+ }
+
+ static const char *file_name[3] = { "test.tscn", "test://.xscn", "?tes*t.scn" };
+ static const bool valid[3] = { true, false, false };
+ for (int i = 0; i < 3; i++) {
+ CHECK(String(file_name[i]).is_valid_filename() == valid[i]);
+ }
+}
+
+TEST_CASE("[String] hash") {
+ String a = "Test";
+ String b = "Test";
+ String c = "West";
+ CHECK(a.hash() == b.hash());
+ CHECK(a.hash() != c.hash());
+
+ CHECK(a.hash64() == b.hash64());
+ CHECK(a.hash64() != c.hash64());
+}
+
+TEST_CASE("[String] http_escape/unescape") {
+ String s = "Godot Engine:'docs'";
+ String t = "Godot%20Engine%3A%27docs%27";
+
+ CHECK(s.http_escape() == t);
+ CHECK(t.http_unescape() == s);
+}
+
+TEST_CASE("[String] percent_encode/decode") { // Note: is it redundant? Seems to be same as http_escape/unescape but in lower case.
+ String s = "Godot Engine:'docs'";
+ String t = "Godot%20Engine%3a%27docs%27";
+
+ CHECK(s.percent_encode() == t);
+ CHECK(t.percent_decode() == s);
+}
+
+TEST_CASE("[String] xml_escape/unescape") {
+ String s = "\"Test\" <test@test&'test'>";
+ CHECK(s.xml_escape(true).xml_unescape() == s);
+ CHECK(s.xml_escape(false).xml_unescape() == s);
+}
+
+TEST_CASE("[String] Strip escapes") {
+ String s = "\t\tTest Test\r\n Test";
+ CHECK(s.strip_escapes() == "Test Test Test");
}
+
+TEST_CASE("[String] Similarity") {
+ String a = "Test";
+ String b = "West";
+ String c = "Toad";
+ CHECK(a.similarity(b) > a.similarity(c));
+}
+
+TEST_CASE("[String] Strip edges") {
+ String s = "\t Test Test ";
+ CHECK(s.strip_edges(true, false) == "Test Test ");
+ CHECK(s.strip_edges(false, true) == "\t Test Test");
+ CHECK(s.strip_edges(true, true) == "Test Test");
+}
+
+TEST_CASE("[String] Trim") {
+ String s = "aaaTestbbb";
+ CHECK(s.trim_prefix("aaa") == "Testbbb");
+ CHECK(s.trim_suffix("bbb") == "aaaTest");
+ CHECK(s.trim_suffix("Test") == s);
+}
+
+TEST_CASE("[String] Right/Left") {
+ String s = "aaaTestbbb";
+ // ^
+ CHECK(s.right(6) == "tbbb");
+ CHECK(s.left(6) == "aaaTes");
+}
+
+TEST_CASE("[String] Repeat") {
+ String s = "abababab";
+ String x = "ab";
+ String t = x.repeat(4);
+ CHECK(t == s);
+}
+
+TEST_CASE("[String] SHA1/SHA256/MD5") {
+ String s = "Godot";
+ String sha1 = "a1e91f39b9fce6a9998b14bdbe2aa2b39dc2d201";
+ static uint8_t sha1_buf[20] = {
+ 0xA1, 0xE9, 0x1F, 0x39, 0xB9, 0xFC, 0xE6, 0xA9, 0x99, 0x8B, 0x14, 0xBD, 0xBE, 0x2A, 0xA2, 0xB3,
+ 0x9D, 0xC2, 0xD2, 0x01
+ };
+ String sha256 = "2a02b2443f7985d89d09001086ae3dcfa6eb0f55c6ef170715d42328e16e6cb8";
+ static uint8_t sha256_buf[32] = {
+ 0x2A, 0x02, 0xB2, 0x44, 0x3F, 0x79, 0x85, 0xD8, 0x9D, 0x09, 0x00, 0x10, 0x86, 0xAE, 0x3D, 0xCF,
+ 0xA6, 0xEB, 0x0F, 0x55, 0xC6, 0xEF, 0x17, 0x07, 0x15, 0xD4, 0x23, 0x28, 0xE1, 0x6E, 0x6C, 0xB8
+ };
+ String md5 = "4a336d087aeb0390da10ee2ea7cb87f8";
+ static uint8_t md5_buf[16] = {
+ 0x4A, 0x33, 0x6D, 0x08, 0x7A, 0xEB, 0x03, 0x90, 0xDA, 0x10, 0xEE, 0x2E, 0xA7, 0xCB, 0x87, 0xF8
+ };
+
+ PackedByteArray buf = s.sha1_buffer();
+ CHECK(memcmp(sha1_buf, buf.ptr(), 20) == 0);
+ CHECK(s.sha1_text() == sha1);
+
+ buf = s.sha256_buffer();
+ CHECK(memcmp(sha256_buf, buf.ptr(), 32) == 0);
+ CHECK(s.sha256_text() == sha256);
+
+ buf = s.md5_buffer();
+ CHECK(memcmp(md5_buf, buf.ptr(), 16) == 0);
+ CHECK(s.md5_text() == md5);
+}
+
+TEST_CASE("[String] Join") {
+ String s = ", ";
+ Vector<String> parts;
+ parts.push_back("One");
+ parts.push_back("B");
+ parts.push_back("C");
+ String t = s.join(parts);
+ CHECK(t == "One, B, C");
+}
+
+TEST_CASE("[String] Is_*") {
+ static const char *data[12] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1" };
+ static bool isnum[12] = { true, true, true, false, false, false, false, false, false, false, false, false };
+ static bool isint[12] = { true, true, false, false, false, false, false, false, false, false, false, false };
+ static bool ishex[12] = { true, true, false, false, true, false, true, false, true, false, false, false };
+ static bool ishex_p[12] = { false, false, false, false, false, false, false, true, false, false, false, false };
+ static bool isflt[12] = { true, true, true, false, true, true, false, false, false, false, false, false };
+ static bool isid[12] = { false, false, false, false, false, false, false, false, true, true, false, false };
+ for (int i = 0; i < 12; i++) {
+ String s = String(data[i]);
+ CHECK(s.is_numeric() == isnum[i]);
+ CHECK(s.is_valid_integer() == isint[i]);
+ CHECK(s.is_valid_hex_number(false) == ishex[i]);
+ CHECK(s.is_valid_hex_number(true) == ishex_p[i]);
+ CHECK(s.is_valid_float() == isflt[i]);
+ CHECK(s.is_valid_identifier() == isid[i]);
+ }
+}
+
+TEST_CASE("[String] humanize_size") {
+ CHECK(String::humanize_size(1000) == "1000 B");
+ CHECK(String::humanize_size(1025) == "1.00 KiB");
+ CHECK(String::humanize_size(1025300) == "1001.2 KiB");
+ CHECK(String::humanize_size(100523550) == "95.86 MiB");
+ CHECK(String::humanize_size(5345555000) == "4.97 GiB");
+}
+
} // namespace TestString
#endif // TEST_STRING_H
diff --git a/thirdparty/README.md b/thirdparty/README.md
index a63eca2a2a..46a75d94b0 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -304,7 +304,7 @@ changes are marked with `// -- GODOT --` comments.
## mbedtls
- Upstream: https://tls.mbed.org/
-- Version: 2.16.7 (2020)
+- Version: 2.16.8 (2020)
- License: Apache 2.0
File extracted from upstream release tarball:
@@ -564,7 +564,7 @@ comments and a patch is provided in the squish/ folder.
## tinyexr
- Upstream: https://github.com/syoyo/tinyexr
-- Version: git (4dbd05a22f51a2d7462311569b8b0cba0bbe2ac5, 2020)
+- Version: 1.0.0 (e4b7840d9448b7d57a88384ce26143004f3c0c71, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -658,7 +658,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.4.4 (2019)
+- Version: 1.4.5 (2020)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h
index d20cdbd6da..4468b6623a 100644
--- a/thirdparty/mbedtls/include/mbedtls/aes.h
+++ b/thirdparty/mbedtls/include/mbedtls/aes.h
@@ -21,7 +21,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -62,8 +62,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AES_H
diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h
index 91a4e0f116..9b63a0010a 100644
--- a/thirdparty/mbedtls/include/mbedtls/aesni.h
+++ b/thirdparty/mbedtls/include/mbedtls/aesni.h
@@ -7,7 +7,7 @@
* functions; you must not call them directly.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -48,8 +48,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AESNI_H
#define MBEDTLS_AESNI_H
diff --git a/thirdparty/mbedtls/include/mbedtls/arc4.h b/thirdparty/mbedtls/include/mbedtls/arc4.h
index ecaf310122..6334a9cc1e 100644
--- a/thirdparty/mbedtls/include/mbedtls/arc4.h
+++ b/thirdparty/mbedtls/include/mbedtls/arc4.h
@@ -7,7 +7,7 @@
* security risk. We recommend considering stronger ciphers instead.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#ifndef MBEDTLS_ARC4_H
#define MBEDTLS_ARC4_H
diff --git a/thirdparty/mbedtls/include/mbedtls/aria.h b/thirdparty/mbedtls/include/mbedtls/aria.h
index 66f2668bf3..13763d4200 100644
--- a/thirdparty/mbedtls/include/mbedtls/aria.h
+++ b/thirdparty/mbedtls/include/mbedtls/aria.h
@@ -10,7 +10,7 @@
* and also described by the IETF in <em>RFC 5794</em>.
*/
/*
- * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -51,8 +51,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ARIA_H
diff --git a/thirdparty/mbedtls/include/mbedtls/asn1.h b/thirdparty/mbedtls/include/mbedtls/asn1.h
index c64038cdb5..0e596bca2c 100644
--- a/thirdparty/mbedtls/include/mbedtls/asn1.h
+++ b/thirdparty/mbedtls/include/mbedtls/asn1.h
@@ -4,7 +4,7 @@
* \brief Generic ASN.1 parsing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
diff --git a/thirdparty/mbedtls/include/mbedtls/asn1write.h b/thirdparty/mbedtls/include/mbedtls/asn1write.h
index 4fed59371c..3c7cdd6b46 100644
--- a/thirdparty/mbedtls/include/mbedtls/asn1write.h
+++ b/thirdparty/mbedtls/include/mbedtls/asn1write.h
@@ -4,7 +4,7 @@
* \brief ASN.1 buffer writing functionality
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
diff --git a/thirdparty/mbedtls/include/mbedtls/base64.h b/thirdparty/mbedtls/include/mbedtls/base64.h
index 215255e628..cbed6887ee 100644
--- a/thirdparty/mbedtls/include/mbedtls/base64.h
+++ b/thirdparty/mbedtls/include/mbedtls/base64.h
@@ -4,7 +4,7 @@
* \brief RFC 1521 base64 encoding/decoding
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BASE64_H
#define MBEDTLS_BASE64_H
diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h
index 590cde58da..4bb9fa3d43 100644
--- a/thirdparty/mbedtls/include/mbedtls/bignum.h
+++ b/thirdparty/mbedtls/include/mbedtls/bignum.h
@@ -4,7 +4,7 @@
* \brief Multi-precision integer library
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
diff --git a/thirdparty/mbedtls/include/mbedtls/blowfish.h b/thirdparty/mbedtls/include/mbedtls/blowfish.h
index d2a1ebdbf4..945bd426a9 100644
--- a/thirdparty/mbedtls/include/mbedtls/blowfish.h
+++ b/thirdparty/mbedtls/include/mbedtls/blowfish.h
@@ -4,7 +4,7 @@
* \brief Blowfish block cipher
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BLOWFISH_H
#define MBEDTLS_BLOWFISH_H
diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
index 42339b7b71..9615090f91 100644
--- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h
+++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
@@ -4,7 +4,7 @@
* \brief Multi-precision integer library
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Multiply source vector [s] with b, add result
diff --git a/thirdparty/mbedtls/include/mbedtls/camellia.h b/thirdparty/mbedtls/include/mbedtls/camellia.h
index 41d6f955ba..38871288e4 100644
--- a/thirdparty/mbedtls/include/mbedtls/camellia.h
+++ b/thirdparty/mbedtls/include/mbedtls/camellia.h
@@ -4,7 +4,7 @@
* \brief Camellia block cipher
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CAMELLIA_H
#define MBEDTLS_CAMELLIA_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h
index 3647d5094f..3dcdc91894 100644
--- a/thirdparty/mbedtls/include/mbedtls/ccm.h
+++ b/thirdparty/mbedtls/include/mbedtls/ccm.h
@@ -28,7 +28,7 @@
* consistent with RFC 3610.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -69,8 +69,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CCM_H
diff --git a/thirdparty/mbedtls/include/mbedtls/certs.h b/thirdparty/mbedtls/include/mbedtls/certs.h
index 2a645ad0d0..8472a6f38c 100644
--- a/thirdparty/mbedtls/include/mbedtls/certs.h
+++ b/thirdparty/mbedtls/include/mbedtls/certs.h
@@ -4,7 +4,7 @@
* \brief Sample certificates and DHM parameters for testing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CERTS_H
#define MBEDTLS_CERTS_H
diff --git a/thirdparty/mbedtls/include/mbedtls/chacha20.h b/thirdparty/mbedtls/include/mbedtls/chacha20.h
index e2950e1a01..8c9c2af6ff 100644
--- a/thirdparty/mbedtls/include/mbedtls/chacha20.h
+++ b/thirdparty/mbedtls/include/mbedtls/chacha20.h
@@ -13,7 +13,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -54,8 +54,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CHACHA20_H
diff --git a/thirdparty/mbedtls/include/mbedtls/chachapoly.h b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
index bee5a3ab03..5f6cb6e030 100644
--- a/thirdparty/mbedtls/include/mbedtls/chachapoly.h
+++ b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
@@ -13,7 +13,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -54,8 +54,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CHACHAPOLY_H
diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h
index 8ce73ceff1..2bbd7a80ff 100644
--- a/thirdparty/mbedtls/include/mbedtls/check_config.h
+++ b/thirdparty/mbedtls/include/mbedtls/check_config.h
@@ -4,7 +4,7 @@
* \brief Consistency checks for configuration options
*/
/*
- * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
@@ -199,6 +197,16 @@
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#define MBEDTLS_HAS_MEMSAN
+#endif
+#endif
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
+#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
+#endif
+#undef MBEDTLS_HAS_MEMSAN
+
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
diff --git a/thirdparty/mbedtls/include/mbedtls/cipher.h b/thirdparty/mbedtls/include/mbedtls/cipher.h
index 8672dd2b98..1f41b528c4 100644
--- a/thirdparty/mbedtls/include/mbedtls/cipher.h
+++ b/thirdparty/mbedtls/include/mbedtls/cipher.h
@@ -8,7 +8,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CIPHER_H
diff --git a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
index 558be52a7e..88282ec9d2 100644
--- a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
@@ -6,7 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
diff --git a/thirdparty/mbedtls/include/mbedtls/cmac.h b/thirdparty/mbedtls/include/mbedtls/cmac.h
index 2074747567..5a7c9b246f 100644
--- a/thirdparty/mbedtls/include/mbedtls/cmac.h
+++ b/thirdparty/mbedtls/include/mbedtls/cmac.h
@@ -7,7 +7,7 @@
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
*/
/*
- * Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -48,8 +48,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CMAC_H
diff --git a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
index 71cc4f4d97..45e5a1cf77 100644
--- a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
+++ b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
@@ -7,7 +7,7 @@
* \deprecated Use the new names directly instead
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -48,8 +48,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h
index 28b405ebca..217998a5eb 100644
--- a/thirdparty/mbedtls/include/mbedtls/config.h
+++ b/thirdparty/mbedtls/include/mbedtls/config.h
@@ -8,7 +8,7 @@
* memory footprint.
*/
/*
- * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CONFIG_H
@@ -552,6 +550,42 @@
//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
/**
+ * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+ *
+ * Enable testing of the constant-flow nature of some sensitive functions with
+ * clang's MemorySanitizer. This causes some existing tests to also test
+ * this non-functional property of the code under test.
+ *
+ * This setting requires compiling with clang -fsanitize=memory. The test
+ * suites can then be run normally.
+ *
+ * \warning This macro is only used for extended testing; it is not considered
+ * part of the library's API, so it may change or disappear at any time.
+ *
+ * Uncomment to enable testing of the constant-flow nature of selected code.
+ */
+//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+
+/**
+ * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+ *
+ * Enable testing of the constant-flow nature of some sensitive functions with
+ * valgrind's memcheck tool. This causes some existing tests to also test
+ * this non-functional property of the code under test.
+ *
+ * This setting requires valgrind headers for building, and is only useful for
+ * testing if the tests suites are run with valgrind's memcheck. This can be
+ * done for an individual test suite with 'valgrind ./test_suite_xxx', or when
+ * using CMake, this can be done for all test suites with 'make memcheck'.
+ *
+ * \warning This macro is only used for extended testing; it is not considered
+ * part of the library's API, so it may change or disappear at any time.
+ *
+ * Uncomment to enable testing of the constant-flow nature of selected code.
+ */
+//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+
+/**
* \def MBEDTLS_TEST_NULL_ENTROPY
*
* Enables testing and use of mbed TLS without any configured entropy sources.
diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
index 894fa17130..7e5f2e5769 100644
--- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
@@ -38,7 +38,7 @@
* - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
*/
/*
- * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -79,8 +79,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CTR_DRBG_H
diff --git a/thirdparty/mbedtls/include/mbedtls/debug.h b/thirdparty/mbedtls/include/mbedtls/debug.h
index 11928e9818..abc2d4f07c 100644
--- a/thirdparty/mbedtls/include/mbedtls/debug.h
+++ b/thirdparty/mbedtls/include/mbedtls/debug.h
@@ -4,7 +4,7 @@
* \brief Functions for controlling and providing debug output from the library.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DEBUG_H
#define MBEDTLS_DEBUG_H
diff --git a/thirdparty/mbedtls/include/mbedtls/des.h b/thirdparty/mbedtls/include/mbedtls/des.h
index 4c6441d7d9..ee24f65945 100644
--- a/thirdparty/mbedtls/include/mbedtls/des.h
+++ b/thirdparty/mbedtls/include/mbedtls/des.h
@@ -8,7 +8,7 @@
* instead.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -50,8 +50,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#ifndef MBEDTLS_DES_H
#define MBEDTLS_DES_H
diff --git a/thirdparty/mbedtls/include/mbedtls/dhm.h b/thirdparty/mbedtls/include/mbedtls/dhm.h
index 5c04ed19fb..11042efb55 100644
--- a/thirdparty/mbedtls/include/mbedtls/dhm.h
+++ b/thirdparty/mbedtls/include/mbedtls/dhm.h
@@ -44,7 +44,7 @@
*
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -85,8 +85,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DHM_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ecdh.h b/thirdparty/mbedtls/include/mbedtls/ecdh.h
index a0052df471..b9324bc496 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecdh.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecdh.h
@@ -13,7 +13,7 @@
* Cryptography</em>.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -54,8 +54,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECDH_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ecdsa.h b/thirdparty/mbedtls/include/mbedtls/ecdsa.h
index bc219dcad7..da02b27864 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecdsa.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecdsa.h
@@ -11,7 +11,7 @@
*
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -52,8 +52,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECDSA_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ecjpake.h b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
index 1b6c6ac244..a9b68d00c6 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecjpake.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
@@ -4,7 +4,7 @@
* \brief Elliptic curve J-PAKE
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ecp.h b/thirdparty/mbedtls/include/mbedtls/ecp.h
index 8db206060b..bdc750eb24 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecp.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecp.h
@@ -15,7 +15,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -56,8 +56,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECP_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
index 4e9445ae44..0047bd4ef9 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
@@ -5,7 +5,7 @@
* point arithmetic.
*/
/*
- * Copyright (C) 2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/include/mbedtls/entropy.h b/thirdparty/mbedtls/include/mbedtls/entropy.h
index fd70cd7e9e..1e1d3f56ec 100644
--- a/thirdparty/mbedtls/include/mbedtls/entropy.h
+++ b/thirdparty/mbedtls/include/mbedtls/entropy.h
@@ -4,7 +4,7 @@
* \brief Entropy accumulator implementation
*/
/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
diff --git a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
index 9843a9e460..c348fe52d4 100644
--- a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
+++ b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
@@ -4,7 +4,7 @@
* \brief Platform-specific and custom entropy polling functions
*/
/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_POLL_H
#define MBEDTLS_ENTROPY_POLL_H
diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h
index 3ee7bbba89..fa8582a391 100644
--- a/thirdparty/mbedtls/include/mbedtls/error.h
+++ b/thirdparty/mbedtls/include/mbedtls/error.h
@@ -4,7 +4,7 @@
* \brief Error to string translation
*/
/*
- * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ERROR_H
#define MBEDTLS_ERROR_H
diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h
index 52d03b0ce8..4e4434ed4d 100644
--- a/thirdparty/mbedtls/include/mbedtls/gcm.h
+++ b/thirdparty/mbedtls/include/mbedtls/gcm.h
@@ -12,7 +12,7 @@
*
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -53,8 +53,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_GCM_H
diff --git a/thirdparty/mbedtls/include/mbedtls/havege.h b/thirdparty/mbedtls/include/mbedtls/havege.h
index 75ab3cb963..e90839ddeb 100644
--- a/thirdparty/mbedtls/include/mbedtls/havege.h
+++ b/thirdparty/mbedtls/include/mbedtls/havege.h
@@ -4,7 +4,7 @@
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HAVEGE_H
#define MBEDTLS_HAVEGE_H
diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h
index a8db554d9f..07ffe83b23 100644
--- a/thirdparty/mbedtls/include/mbedtls/hkdf.h
+++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h
@@ -7,7 +7,7 @@
* specified by RFC 5869.
*/
/*
- * Copyright (C) 2016-2019, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -48,8 +48,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
index 231fb459bc..6883678204 100644
--- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
@@ -8,7 +8,7 @@
* Deterministic Random Bit Generators</em>.
*/
/*
- * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HMAC_DRBG_H
#define MBEDTLS_HMAC_DRBG_H
diff --git a/thirdparty/mbedtls/include/mbedtls/md.h b/thirdparty/mbedtls/include/mbedtls/md.h
index 6a21f05908..2ba8d9e7a9 100644
--- a/thirdparty/mbedtls/include/mbedtls/md.h
+++ b/thirdparty/mbedtls/include/mbedtls/md.h
@@ -6,7 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_H
diff --git a/thirdparty/mbedtls/include/mbedtls/md2.h b/thirdparty/mbedtls/include/mbedtls/md2.h
index 6d563b41be..9607df66ba 100644
--- a/thirdparty/mbedtls/include/mbedtls/md2.h
+++ b/thirdparty/mbedtls/include/mbedtls/md2.h
@@ -8,7 +8,7 @@
* instead.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -50,8 +50,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#ifndef MBEDTLS_MD2_H
#define MBEDTLS_MD2_H
diff --git a/thirdparty/mbedtls/include/mbedtls/md4.h b/thirdparty/mbedtls/include/mbedtls/md4.h
index 3f4bcdc607..6ceaf7a2f6 100644
--- a/thirdparty/mbedtls/include/mbedtls/md4.h
+++ b/thirdparty/mbedtls/include/mbedtls/md4.h
@@ -8,7 +8,7 @@
* instead.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -50,8 +50,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#ifndef MBEDTLS_MD4_H
#define MBEDTLS_MD4_H
diff --git a/thirdparty/mbedtls/include/mbedtls/md5.h b/thirdparty/mbedtls/include/mbedtls/md5.h
index 34279c7212..b9d0ca929a 100644
--- a/thirdparty/mbedtls/include/mbedtls/md5.h
+++ b/thirdparty/mbedtls/include/mbedtls/md5.h
@@ -8,7 +8,7 @@
* digests instead.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD5_H
#define MBEDTLS_MD5_H
diff --git a/thirdparty/mbedtls/include/mbedtls/md_internal.h b/thirdparty/mbedtls/include/mbedtls/md_internal.h
index 154b8bbc27..847f50aa0a 100644
--- a/thirdparty/mbedtls/include/mbedtls/md_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/md_internal.h
@@ -8,7 +8,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
diff --git a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
index c1e0926b13..89c0617495 100644
--- a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
+++ b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
@@ -4,7 +4,7 @@
* \brief Buffer-based memory allocator
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
diff --git a/thirdparty/mbedtls/include/mbedtls/net.h b/thirdparty/mbedtls/include/mbedtls/net.h
index bba4a35940..6c7a49d3bd 100644
--- a/thirdparty/mbedtls/include/mbedtls/net.h
+++ b/thirdparty/mbedtls/include/mbedtls/net.h
@@ -6,7 +6,7 @@
* \deprecated Superseded by mbedtls/net_sockets.h
*/
/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
diff --git a/thirdparty/mbedtls/include/mbedtls/net_sockets.h b/thirdparty/mbedtls/include/mbedtls/net_sockets.h
index d4d23fe9d8..00fea7db19 100644
--- a/thirdparty/mbedtls/include/mbedtls/net_sockets.h
+++ b/thirdparty/mbedtls/include/mbedtls/net_sockets.h
@@ -20,7 +20,7 @@
*
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -61,8 +61,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_NET_SOCKETS_H
#define MBEDTLS_NET_SOCKETS_H
diff --git a/thirdparty/mbedtls/include/mbedtls/nist_kw.h b/thirdparty/mbedtls/include/mbedtls/nist_kw.h
index f2b9cebf9c..9435656994 100644
--- a/thirdparty/mbedtls/include/mbedtls/nist_kw.h
+++ b/thirdparty/mbedtls/include/mbedtls/nist_kw.h
@@ -16,7 +16,7 @@
*
*/
/*
- * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -57,8 +57,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_NIST_KW_H
diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h
index 7fe4b38621..4a7e3b4b3f 100644
--- a/thirdparty/mbedtls/include/mbedtls/oid.h
+++ b/thirdparty/mbedtls/include/mbedtls/oid.h
@@ -4,7 +4,7 @@
* \brief Object Identifier (OID) database
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_OID_H
#define MBEDTLS_OID_H
diff --git a/thirdparty/mbedtls/include/mbedtls/padlock.h b/thirdparty/mbedtls/include/mbedtls/padlock.h
index bd476f5f38..d8246e2cd0 100644
--- a/thirdparty/mbedtls/include/mbedtls/padlock.h
+++ b/thirdparty/mbedtls/include/mbedtls/padlock.h
@@ -8,7 +8,7 @@
* functions; you must not call them directly.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -49,8 +49,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PADLOCK_H
#define MBEDTLS_PADLOCK_H
diff --git a/thirdparty/mbedtls/include/mbedtls/pem.h b/thirdparty/mbedtls/include/mbedtls/pem.h
index 16b6101415..c9df7ca6e8 100644
--- a/thirdparty/mbedtls/include/mbedtls/pem.h
+++ b/thirdparty/mbedtls/include/mbedtls/pem.h
@@ -4,7 +4,7 @@
* \brief Privacy Enhanced Mail (PEM) decoding
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PEM_H
#define MBEDTLS_PEM_H
@@ -139,17 +137,27 @@ void mbedtls_pem_free( mbedtls_pem_context *ctx );
* \brief Write a buffer of PEM information from a DER encoded
* buffer.
*
- * \param header header string to write
- * \param footer footer string to write
- * \param der_data DER data to write
- * \param der_len length of the DER data
- * \param buf buffer to write to
- * \param buf_len length of output buffer
- * \param olen total length written / required (if buf_len is not enough)
- *
- * \return 0 on success, or a specific PEM or BASE64 error code. On
- * MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
- * size.
+ * \param header The header string to write.
+ * \param footer The footer string to write.
+ * \param der_data The DER data to encode.
+ * \param der_len The length of the DER data \p der_data in Bytes.
+ * \param buf The buffer to write to.
+ * \param buf_len The length of the output buffer \p buf in Bytes.
+ * \param olen The address at which to store the total length written
+ * or required (if \p buf_len is not enough).
+ *
+ * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len
+ * to request the length of the resulting PEM buffer in
+ * `*olen`.
+ *
+ * \note This function may be called with overlapping \p der_data
+ * and \p buf buffers.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
+ * enough to hold the PEM buffer. In this case, `*olen` holds
+ * the required minimum size of \p buf.
+ * \return Another PEM or BASE64 error code on other kinds of failure.
*/
int mbedtls_pem_write_buffer( const char *header, const char *footer,
const unsigned char *der_data, size_t der_len,
diff --git a/thirdparty/mbedtls/include/mbedtls/pk.h b/thirdparty/mbedtls/include/mbedtls/pk.h
index 408f7baee7..20d51d4f38 100644
--- a/thirdparty/mbedtls/include/mbedtls/pk.h
+++ b/thirdparty/mbedtls/include/mbedtls/pk.h
@@ -4,7 +4,7 @@
* \brief Public Key abstraction layer
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PK_H
diff --git a/thirdparty/mbedtls/include/mbedtls/pk_internal.h b/thirdparty/mbedtls/include/mbedtls/pk_internal.h
index 1cd05943ba..3f84cdf748 100644
--- a/thirdparty/mbedtls/include/mbedtls/pk_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/pk_internal.h
@@ -4,7 +4,7 @@
* \brief Public Key abstraction layer: wrapper functions
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PK_WRAP_H
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs11.h b/thirdparty/mbedtls/include/mbedtls/pkcs11.h
index e1446120c8..3874d4a05e 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs11.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs11.h
@@ -6,7 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PKCS11_H
#define MBEDTLS_PKCS11_H
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs12.h b/thirdparty/mbedtls/include/mbedtls/pkcs12.h
index c418e8f243..9cbcb17305 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs12.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs12.h
@@ -4,7 +4,7 @@
* \brief PKCS#12 Personal Information Exchange Syntax
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PKCS12_H
#define MBEDTLS_PKCS12_H
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs5.h b/thirdparty/mbedtls/include/mbedtls/pkcs5.h
index c3f645aff1..328633c492 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs5.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs5.h
@@ -6,7 +6,7 @@
* \author Mathias Olsson <mathias@kompetensum.com>
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PKCS5_H
#define MBEDTLS_PKCS5_H
diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h
index dcb5a88eeb..689cfc6ec7 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform.h
@@ -13,7 +13,7 @@
* dynamically configured at runtime.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -54,8 +54,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_H
#define MBEDTLS_PLATFORM_H
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_time.h b/thirdparty/mbedtls/include/mbedtls/platform_time.h
index a45870c3a6..e132f6a688 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_time.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_time.h
@@ -4,7 +4,7 @@
* \brief mbed TLS Platform time abstraction
*/
/*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_TIME_H
#define MBEDTLS_PLATFORM_TIME_H
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_util.h b/thirdparty/mbedtls/include/mbedtls/platform_util.h
index f10574afe6..426afaf040 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_util.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_util.h
@@ -5,7 +5,7 @@
* library.
*/
/*
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H
diff --git a/thirdparty/mbedtls/include/mbedtls/poly1305.h b/thirdparty/mbedtls/include/mbedtls/poly1305.h
index 6e45b2c2ba..b337aa841c 100644
--- a/thirdparty/mbedtls/include/mbedtls/poly1305.h
+++ b/thirdparty/mbedtls/include/mbedtls/poly1305.h
@@ -13,7 +13,7 @@
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -54,8 +54,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_POLY1305_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h
index 505c39252e..31c6637d6d 100644
--- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h
+++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h
@@ -4,7 +4,7 @@
* \brief RIPE MD-160 message digest
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_RIPEMD160_H
#define MBEDTLS_RIPEMD160_H
diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h
index cd22fc4c1f..188c37cf3a 100644
--- a/thirdparty/mbedtls/include/mbedtls/rsa.h
+++ b/thirdparty/mbedtls/include/mbedtls/rsa.h
@@ -10,7 +10,7 @@
*
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -51,8 +51,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_RSA_H
#define MBEDTLS_RSA_H
diff --git a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
index 2464e6b082..953cb7b81d 100644
--- a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
@@ -35,7 +35,7 @@
*
*/
/*
- * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -77,8 +77,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#ifndef MBEDTLS_RSA_INTERNAL_H
diff --git a/thirdparty/mbedtls/include/mbedtls/sha1.h b/thirdparty/mbedtls/include/mbedtls/sha1.h
index e69db8a15a..60c514a49e 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha1.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha1.h
@@ -11,7 +11,7 @@
* digests instead.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -52,8 +52,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA1_H
#define MBEDTLS_SHA1_H
diff --git a/thirdparty/mbedtls/include/mbedtls/sha256.h b/thirdparty/mbedtls/include/mbedtls/sha256.h
index 5b03bc31dc..b1881e183c 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha256.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha256.h
@@ -7,7 +7,7 @@
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -48,8 +48,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA256_H
#define MBEDTLS_SHA256_H
diff --git a/thirdparty/mbedtls/include/mbedtls/sha512.h b/thirdparty/mbedtls/include/mbedtls/sha512.h
index 2fbc69f80e..9ff78ecf41 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha512.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha512.h
@@ -6,7 +6,7 @@
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
*/
/*
- * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -47,8 +47,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SHA512_H
#define MBEDTLS_SHA512_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h
index 6f56983562..d3ee3c4e6f 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl.h
@@ -4,7 +4,7 @@
* \brief SSL/TLS functions.
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_H
#define MBEDTLS_SSL_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
index e987c29e11..612d81776e 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
@@ -4,7 +4,7 @@
* \brief SSL session cache implementation
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_CACHE_H
#define MBEDTLS_SSL_CACHE_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
index 8969141165..ab8e601db7 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
@@ -4,7 +4,7 @@
* \brief SSL Ciphersuites for mbed TLS
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_CIPHERSUITES_H
#define MBEDTLS_SSL_CIPHERSUITES_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
index 71e056781c..9c2d5b62a4 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
@@ -4,7 +4,7 @@
* \brief DTLS cookie callbacks implementation
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_COOKIE_H
#define MBEDTLS_SSL_COOKIE_H
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
index b371094f1e..6ba6c2af09 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
@@ -4,7 +4,7 @@
* \brief Internal functions shared by the SSL modules
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_INTERNAL_H
#define MBEDTLS_SSL_INTERNAL_H
@@ -152,6 +150,24 @@
#define MBEDTLS_SSL_RETRANS_WAITING 2
#define MBEDTLS_SSL_RETRANS_FINISHED 3
+/* This macro determines whether CBC is supported. */
+#if defined(MBEDTLS_CIPHER_MODE_CBC) && \
+ ( defined(MBEDTLS_AES_C) || \
+ defined(MBEDTLS_CAMELLIA_C) || \
+ defined(MBEDTLS_ARIA_C) || \
+ defined(MBEDTLS_DES_C) )
+#define MBEDTLS_SSL_SOME_SUITES_USE_CBC
+#endif
+
+/* This macro determines whether the CBC construct used in TLS 1.0-1.2 (as
+ * opposed to the very different CBC construct used in SSLv3) is supported. */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
+ ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2) )
+#define MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC
+#endif
+
/*
* Allow extra bytes for record, authentication and encryption overhead:
* counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
@@ -843,6 +859,73 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+/** \brief Compute the HMAC of variable-length data with constant flow.
+ *
+ * This function computes the HMAC of the concatenation of \p add_data and \p
+ * data, and does with a code flow and memory access pattern that does not
+ * depend on \p data_len_secret, but only on \p min_data_len and \p
+ * max_data_len. In particular, this function always reads exactly \p
+ * max_data_len bytes from \p data.
+ *
+ * \param ctx The HMAC context. It must have keys configured
+ * with mbedtls_md_hmac_starts() and use one of the
+ * following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
+ * It is reset using mbedtls_md_hmac_reset() after
+ * the computation is complete to prepare for the
+ * next computation.
+ * \param add_data The additional data prepended to \p data. This
+ * must point to a readable buffer of \p add_data_len
+ * bytes.
+ * \param add_data_len The length of \p add_data in bytes.
+ * \param data The data appended to \p add_data. This must point
+ * to a readable buffer of \p max_data_len bytes.
+ * \param data_len_secret The length of the data to process in \p data.
+ * This must be no less than \p min_data_len and no
+ * greater than \p max_data_len.
+ * \param min_data_len The minimal length of \p data in bytes.
+ * \param max_data_len The maximal length of \p data in bytes.
+ * \param output The HMAC will be written here. This must point to
+ * a writable buffer of sufficient size to hold the
+ * HMAC value.
+ *
+ * \retval 0
+ * Success.
+ * \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
+ * The hardware accelerator failed.
+ */
+int mbedtls_ssl_cf_hmac(
+ mbedtls_md_context_t *ctx,
+ const unsigned char *add_data, size_t add_data_len,
+ const unsigned char *data, size_t data_len_secret,
+ size_t min_data_len, size_t max_data_len,
+ unsigned char *output );
+
+/** \brief Copy data from a secret position with constant flow.
+ *
+ * This function copies \p len bytes from \p src_base + \p offset_secret to \p
+ * dst, with a code flow and memory access pattern that does not depend on \p
+ * offset_secret, but only on \p offset_min, \p offset_max and \p len.
+ *
+ * \param dst The destination buffer. This must point to a writable
+ * buffer of at least \p len bytes.
+ * \param src_base The base of the source buffer. This must point to a
+ * readable buffer of at least \p offset_max + \p len
+ * bytes.
+ * \param offset_secret The offset in the source buffer from which to copy.
+ * This must be no less than \p offset_min and no greater
+ * than \p offset_max.
+ * \param offset_min The minimal value of \p offset_secret.
+ * \param offset_max The maximal value of \p offset_secret.
+ * \param len The number of bytes to copy.
+ */
+void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
+ const unsigned char *src_base,
+ size_t offset_secret,
+ size_t offset_min, size_t offset_max,
+ size_t len );
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
index ac3be04337..a10a434138 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
@@ -4,7 +4,7 @@
* \brief TLS server ticket callbacks implementation
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_SSL_TICKET_H
#define MBEDTLS_SSL_TICKET_H
diff --git a/thirdparty/mbedtls/include/mbedtls/threading.h b/thirdparty/mbedtls/include/mbedtls/threading.h
index b6ec4df8e9..a8183a6ef4 100644
--- a/thirdparty/mbedtls/include/mbedtls/threading.h
+++ b/thirdparty/mbedtls/include/mbedtls/threading.h
@@ -4,7 +4,7 @@
* \brief Threading abstraction layer
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_THREADING_H
#define MBEDTLS_THREADING_H
diff --git a/thirdparty/mbedtls/include/mbedtls/timing.h b/thirdparty/mbedtls/include/mbedtls/timing.h
index 149ccfb666..8611ba9a4e 100644
--- a/thirdparty/mbedtls/include/mbedtls/timing.h
+++ b/thirdparty/mbedtls/include/mbedtls/timing.h
@@ -4,7 +4,7 @@
* \brief Portable interface to timeouts and to the CPU cycle counter
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_TIMING_H
#define MBEDTLS_TIMING_H
diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h
index 2bff31d51f..d09b45002d 100644
--- a/thirdparty/mbedtls/include/mbedtls/version.h
+++ b/thirdparty/mbedtls/include/mbedtls/version.h
@@ -4,7 +4,7 @@
* \brief Run-time version information
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* This set of compile-time defines and run-time variables can be used to
@@ -67,16 +65,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 16
-#define MBEDTLS_VERSION_PATCH 7
+#define MBEDTLS_VERSION_PATCH 8
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02100700
-#define MBEDTLS_VERSION_STRING "2.16.7"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.7"
+#define MBEDTLS_VERSION_NUMBER 0x02100800
+#define MBEDTLS_VERSION_STRING "2.16.8"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.8"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/include/mbedtls/x509.h b/thirdparty/mbedtls/include/mbedtls/x509.h
index e9f2fc6024..5bb9b00292 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509.h
@@ -4,7 +4,7 @@
* \brief X.509 generic defines and structures
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_X509_H
#define MBEDTLS_X509_H
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crl.h b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
index 0e37f65e8f..2ade47c89d 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crl.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
@@ -4,7 +4,7 @@
* \brief X.509 certificate revocation list parsing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_X509_CRL_H
#define MBEDTLS_X509_CRL_H
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crt.h b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
index 4aae923ea0..c38e0c0556 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crt.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
@@ -4,7 +4,7 @@
* \brief X.509 certificate parsing and writing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_X509_CRT_H
#define MBEDTLS_X509_CRT_H
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_csr.h b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
index 8ba2cda0dc..5dfb4213e8 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_csr.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
@@ -4,7 +4,7 @@
* \brief X.509 certificate signing request parsing and writing
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_X509_CSR_H
#define MBEDTLS_X509_CSR_H
diff --git a/thirdparty/mbedtls/include/mbedtls/xtea.h b/thirdparty/mbedtls/include/mbedtls/xtea.h
index d372110215..cd6d3753d1 100644
--- a/thirdparty/mbedtls/include/mbedtls/xtea.h
+++ b/thirdparty/mbedtls/include/mbedtls/xtea.h
@@ -4,7 +4,7 @@
* \brief XTEA block cipher (32-bit)
*/
/*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -45,8 +45,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_XTEA_H
#define MBEDTLS_XTEA_H
diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c
index 9ec28690b2..9b337505fd 100644
--- a/thirdparty/mbedtls/library/aes.c
+++ b/thirdparty/mbedtls/library/aes.c
@@ -1,7 +1,7 @@
/*
* FIPS-197 compliant AES implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
diff --git a/thirdparty/mbedtls/library/aesni.c b/thirdparty/mbedtls/library/aesni.c
index 44bd89cba9..358d4ad860 100644
--- a/thirdparty/mbedtls/library/aesni.c
+++ b/thirdparty/mbedtls/library/aesni.c
@@ -1,7 +1,7 @@
/*
* AES-NI support functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/arc4.c b/thirdparty/mbedtls/library/arc4.c
index c30facb671..6729bab002 100644
--- a/thirdparty/mbedtls/library/arc4.c
+++ b/thirdparty/mbedtls/library/arc4.c
@@ -1,7 +1,7 @@
/*
* An implementation of the ARCFOUR algorithm
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
diff --git a/thirdparty/mbedtls/library/aria.c b/thirdparty/mbedtls/library/aria.c
index 0c9dd76f07..ef0392f658 100644
--- a/thirdparty/mbedtls/library/aria.c
+++ b/thirdparty/mbedtls/library/aria.c
@@ -1,7 +1,7 @@
/*
* ARIA implementation
*
- * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/asn1parse.c b/thirdparty/mbedtls/library/asn1parse.c
index 8d59119ae0..10239fdd15 100644
--- a/thirdparty/mbedtls/library/asn1parse.c
+++ b/thirdparty/mbedtls/library/asn1parse.c
@@ -1,7 +1,7 @@
/*
* Generic ASN.1 parsing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c
index bd0d6af4d8..d94d0a7605 100644
--- a/thirdparty/mbedtls/library/asn1write.c
+++ b/thirdparty/mbedtls/library/asn1write.c
@@ -1,7 +1,7 @@
/*
* ASN.1 buffer writing functionality
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/base64.c b/thirdparty/mbedtls/library/base64.c
index 75849d1214..bfafb05353 100644
--- a/thirdparty/mbedtls/library/base64.c
+++ b/thirdparty/mbedtls/library/base64.c
@@ -1,7 +1,7 @@
/*
* RFC 1521 base64 encoding/decoding
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c
index f42b97650f..dfe976d648 100644
--- a/thirdparty/mbedtls/library/bignum.c
+++ b/thirdparty/mbedtls/library/bignum.c
@@ -1,7 +1,7 @@
/*
* Multi-precision integer library
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/blowfish.c b/thirdparty/mbedtls/library/blowfish.c
index f11a9d6395..a3f9be959f 100644
--- a/thirdparty/mbedtls/library/blowfish.c
+++ b/thirdparty/mbedtls/library/blowfish.c
@@ -1,7 +1,7 @@
/*
* Blowfish implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
diff --git a/thirdparty/mbedtls/library/camellia.c b/thirdparty/mbedtls/library/camellia.c
index 9f5724917b..40d62121bf 100644
--- a/thirdparty/mbedtls/library/camellia.c
+++ b/thirdparty/mbedtls/library/camellia.c
@@ -1,7 +1,7 @@
/*
* Camellia implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The Camellia block cipher was designed by NTT and Mitsubishi Electric
diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c
index 18a2343ac5..b2e5a4763d 100644
--- a/thirdparty/mbedtls/library/ccm.c
+++ b/thirdparty/mbedtls/library/ccm.c
@@ -1,7 +1,7 @@
/*
* NIST SP800-38C compliant CCM implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/certs.c b/thirdparty/mbedtls/library/certs.c
index 7423168b25..cb43f53368 100644
--- a/thirdparty/mbedtls/library/certs.c
+++ b/thirdparty/mbedtls/library/certs.c
@@ -1,7 +1,7 @@
/*
* X.509 test certificates
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c
index d851a25bd6..80fe50cc67 100644
--- a/thirdparty/mbedtls/library/chacha20.c
+++ b/thirdparty/mbedtls/library/chacha20.c
@@ -5,7 +5,7 @@
*
* \author Daniel King <damaki.gh@gmail.com>
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c
index f232190dfc..c8b5bba4b2 100644
--- a/thirdparty/mbedtls/library/chachapoly.c
+++ b/thirdparty/mbedtls/library/chachapoly.c
@@ -3,7 +3,7 @@
*
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -44,8 +44,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c
index 896ec8ec66..57da0b9c44 100644
--- a/thirdparty/mbedtls/library/cipher.c
+++ b/thirdparty/mbedtls/library/cipher.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c
index 09296c7f9b..1dcac21be1 100644
--- a/thirdparty/mbedtls/library/cipher_wrap.c
+++ b/thirdparty/mbedtls/library/cipher_wrap.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/cmac.c b/thirdparty/mbedtls/library/cmac.c
index ce0cd4b055..1a1200b52b 100644
--- a/thirdparty/mbedtls/library/cmac.c
+++ b/thirdparty/mbedtls/library/cmac.c
@@ -3,7 +3,7 @@
*
* \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -44,8 +44,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c
index e1900afc45..b98df29a9b 100644
--- a/thirdparty/mbedtls/library/ctr_drbg.c
+++ b/thirdparty/mbedtls/library/ctr_drbg.c
@@ -1,7 +1,7 @@
/*
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The NIST SP 800-90 DRBGs are described in the following publication.
diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c
index 3604cfb253..5f06d0da13 100644
--- a/thirdparty/mbedtls/library/debug.c
+++ b/thirdparty/mbedtls/library/debug.c
@@ -1,7 +1,7 @@
/*
* Debugging routines
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c
index a5f73330b0..623165d391 100644
--- a/thirdparty/mbedtls/library/des.c
+++ b/thirdparty/mbedtls/library/des.c
@@ -1,7 +1,7 @@
/*
* FIPS-46-3 compliant Triple-DES implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c
index f8d367ee89..d652cf0ac9 100644
--- a/thirdparty/mbedtls/library/dhm.c
+++ b/thirdparty/mbedtls/library/dhm.c
@@ -1,7 +1,7 @@
/*
* Diffie-Hellman-Merkle key exchange
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The following sources were referenced in the design of this implementation
@@ -351,6 +349,32 @@ cleanup:
}
/*
+ * Pick a random R in the range [2, M) for blinding purposes
+ */
+static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret, count;
+
+ count = 0;
+ do
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
+
+ while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
+
+ if( count++ > 10 )
+ return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+ }
+ while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
+
+cleanup:
+ return( ret );
+}
+
+
+/*
* Use the blinding method and optimisation suggested in section 10 of:
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
* DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
@@ -359,7 +383,10 @@ cleanup:
static int dhm_update_blinding( mbedtls_dhm_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret, count;
+ int ret;
+ mbedtls_mpi R;
+
+ mbedtls_mpi_init( &R );
/*
* Don't use any blinding the first time a particular X is used,
@@ -394,24 +421,23 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx,
*/
/* Vi = random( 2, P-1 ) */
- count = 0;
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
-
- while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
-
- if( count++ > 10 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
- }
- while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
+ MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
+
+ /* Vf = Vi^-X mod P
+ * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
+ * then elevate to the Xth power. */
+ MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
- /* Vf = Vi^-X mod P */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
cleanup:
+ mbedtls_mpi_free( &R );
+
return( ret );
}
diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c
index 5ef205f36d..8c27e4e196 100644
--- a/thirdparty/mbedtls/library/ecdh.c
+++ b/thirdparty/mbedtls/library/ecdh.c
@@ -1,7 +1,7 @@
/*
* Elliptic curve Diffie-Hellman
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c
index 08fda3fa9b..da8df9cde2 100644
--- a/thirdparty/mbedtls/library/ecdsa.c
+++ b/thirdparty/mbedtls/library/ecdsa.c
@@ -1,7 +1,7 @@
/*
* Elliptic curve DSA
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c
index c89163c68a..f6e24580c7 100644
--- a/thirdparty/mbedtls/library/ecjpake.c
+++ b/thirdparty/mbedtls/library/ecjpake.c
@@ -1,7 +1,7 @@
/*
* Elliptic curve J-PAKE
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index 7ea8b1676a..fe41b4128a 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -1,7 +1,7 @@
/*
* Elliptic curves over GF(p): generic functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c
index 796e0d1250..cc4c5b71c0 100644
--- a/thirdparty/mbedtls/library/ecp_curves.c
+++ b/thirdparty/mbedtls/library/ecp_curves.c
@@ -1,7 +1,7 @@
/*
* Elliptic curves over GF(p): curve-specific data and functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/entropy.c b/thirdparty/mbedtls/library/entropy.c
index 1bd6ce54ee..666c55654c 100644
--- a/thirdparty/mbedtls/library/entropy.c
+++ b/thirdparty/mbedtls/library/entropy.c
@@ -1,7 +1,7 @@
/*
* Entropy accumulator implementation
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c
index a5996a198d..26b7e4e2b9 100644
--- a/thirdparty/mbedtls/library/entropy_poll.c
+++ b/thirdparty/mbedtls/library/entropy_poll.c
@@ -1,7 +1,7 @@
/*
* Platform-specific and custom entropy polling functions
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if defined(__linux__)
diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c
index 4ab8733e0c..eb52052b51 100644
--- a/thirdparty/mbedtls/library/error.c
+++ b/thirdparty/mbedtls/library/error.c
@@ -1,7 +1,7 @@
/*
* Error message information
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c
index 7edc6da366..2afe5025a0 100644
--- a/thirdparty/mbedtls/library/gcm.c
+++ b/thirdparty/mbedtls/library/gcm.c
@@ -1,7 +1,7 @@
/*
* NIST SP800-38D compliant GCM implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/havege.c b/thirdparty/mbedtls/library/havege.c
index 800a518a66..5e91f40d84 100644
--- a/thirdparty/mbedtls/library/havege.c
+++ b/thirdparty/mbedtls/library/havege.c
@@ -1,7 +1,7 @@
/**
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
diff --git a/thirdparty/mbedtls/library/hkdf.c b/thirdparty/mbedtls/library/hkdf.c
index 0dd4d05645..4a8bdfbe18 100644
--- a/thirdparty/mbedtls/library/hkdf.c
+++ b/thirdparty/mbedtls/library/hkdf.c
@@ -1,7 +1,7 @@
/*
* HKDF implementation -- RFC 5869
*
- * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
diff --git a/thirdparty/mbedtls/library/hmac_drbg.c b/thirdparty/mbedtls/library/hmac_drbg.c
index 2cb108c406..9fbfc30660 100644
--- a/thirdparty/mbedtls/library/hmac_drbg.c
+++ b/thirdparty/mbedtls/library/hmac_drbg.c
@@ -1,7 +1,7 @@
/*
* HMAC_DRBG implementation (NIST SP 800-90)
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/md.c b/thirdparty/mbedtls/library/md.c
index bfada3c058..867b91462d 100644
--- a/thirdparty/mbedtls/library/md.c
+++ b/thirdparty/mbedtls/library/md.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c
index d772039b79..cbdaaabdc7 100644
--- a/thirdparty/mbedtls/library/md2.c
+++ b/thirdparty/mbedtls/library/md2.c
@@ -1,7 +1,7 @@
/*
* RFC 1115/1319 compliant MD2 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c
index 56b359ce34..cb16dce54a 100644
--- a/thirdparty/mbedtls/library/md4.c
+++ b/thirdparty/mbedtls/library/md4.c
@@ -1,7 +1,7 @@
/*
* RFC 1186/1320 compliant MD4 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c
index 31879a9b14..fe25925214 100644
--- a/thirdparty/mbedtls/library/md5.c
+++ b/thirdparty/mbedtls/library/md5.c
@@ -1,7 +1,7 @@
/*
* RFC 1321 compliant MD5 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
diff --git a/thirdparty/mbedtls/library/md_wrap.c b/thirdparty/mbedtls/library/md_wrap.c
index 7c737d87e9..7459db2faf 100644
--- a/thirdparty/mbedtls/library/md_wrap.c
+++ b/thirdparty/mbedtls/library/md_wrap.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c
index e854eea8ee..915ec3ae9d 100644
--- a/thirdparty/mbedtls/library/memory_buffer_alloc.c
+++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c
@@ -1,7 +1,7 @@
/*
* Buffer-based memory allocator
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c
index 9489576aae..1130408263 100644
--- a/thirdparty/mbedtls/library/net_sockets.c
+++ b/thirdparty/mbedtls/library/net_sockets.c
@@ -1,7 +1,7 @@
/*
* TCP/IP or UDP/IP networking functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
@@ -51,6 +49,10 @@
* Harmless on other platforms. */
#define _POSIX_C_SOURCE 200112L
+#if defined(__NetBSD__)
+#define _XOPEN_SOURCE 600 /* sockaddr_storage */
+#endif
+
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@@ -345,8 +347,9 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
struct sockaddr_storage client_addr;
-#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
- defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
+#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
+ defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \
+ ( defined(__NetBSD__) && defined(socklen_t) )
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
#else
diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c
index 35be530957..8341ff1303 100644
--- a/thirdparty/mbedtls/library/nist_kw.c
+++ b/thirdparty/mbedtls/library/nist_kw.c
@@ -2,7 +2,7 @@
* Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes
* only
*
- * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -43,8 +43,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
/*
* Definition of Key Wrapping:
diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c
index 0a1658f821..2414083f0c 100644
--- a/thirdparty/mbedtls/library/oid.c
+++ b/thirdparty/mbedtls/library/oid.c
@@ -3,7 +3,7 @@
*
* \brief Object Identifier (OID) database
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -44,8 +44,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/padlock.c b/thirdparty/mbedtls/library/padlock.c
index fe6e7f9cf3..afb7e0ad42 100644
--- a/thirdparty/mbedtls/library/padlock.c
+++ b/thirdparty/mbedtls/library/padlock.c
@@ -1,7 +1,7 @@
/*
* VIA PadLock support functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c
index 3bf4ca5b8c..a7a2f7f5cf 100644
--- a/thirdparty/mbedtls/library/pem.c
+++ b/thirdparty/mbedtls/library/pem.c
@@ -1,7 +1,7 @@
/*
* Privacy Enhanced Mail (PEM) decoding
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/pk.c b/thirdparty/mbedtls/library/pk.c
index e9e56c029b..81cfdbfe80 100644
--- a/thirdparty/mbedtls/library/pk.c
+++ b/thirdparty/mbedtls/library/pk.c
@@ -1,7 +1,7 @@
/*
* Public Key abstraction layer
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/pk_wrap.c b/thirdparty/mbedtls/library/pk_wrap.c
index 21a7a33d82..2c27552d9b 100644
--- a/thirdparty/mbedtls/library/pk_wrap.c
+++ b/thirdparty/mbedtls/library/pk_wrap.c
@@ -1,7 +1,7 @@
/*
* Public Key abstraction layer: wrapper functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/pkcs11.c b/thirdparty/mbedtls/library/pkcs11.c
index 30d045bf18..cf484b86eb 100644
--- a/thirdparty/mbedtls/library/pkcs11.c
+++ b/thirdparty/mbedtls/library/pkcs11.c
@@ -5,7 +5,7 @@
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#include "mbedtls/pkcs11.h"
diff --git a/thirdparty/mbedtls/library/pkcs12.c b/thirdparty/mbedtls/library/pkcs12.c
index 3c34128682..3d23d5e354 100644
--- a/thirdparty/mbedtls/library/pkcs12.c
+++ b/thirdparty/mbedtls/library/pkcs12.c
@@ -1,7 +1,7 @@
/*
* PKCS#12 Personal Information Exchange Syntax
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The PKCS #12 Personal Information Exchange Syntax Standard v1.1
diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c
index 7ac67093c0..8a80aa5d05 100644
--- a/thirdparty/mbedtls/library/pkcs5.c
+++ b/thirdparty/mbedtls/library/pkcs5.c
@@ -5,7 +5,7 @@
*
* \author Mathias Olsson <mathias@kompetensum.com>
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -46,8 +46,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* PKCS#5 includes PBKDF2 and more
diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c
index 624ca4c671..086807d836 100644
--- a/thirdparty/mbedtls/library/pkparse.c
+++ b/thirdparty/mbedtls/library/pkparse.c
@@ -1,7 +1,7 @@
/*
* Public Key layer for parsing key files and structures
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/pkwrite.c b/thirdparty/mbedtls/library/pkwrite.c
index 76159e5a80..150626c147 100644
--- a/thirdparty/mbedtls/library/pkwrite.c
+++ b/thirdparty/mbedtls/library/pkwrite.c
@@ -1,7 +1,7 @@
/*
* Public Key layer for writing key files and structures
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c
index 7fe5e56b71..c4c3fd332d 100644
--- a/thirdparty/mbedtls/library/platform.c
+++ b/thirdparty/mbedtls/library/platform.c
@@ -1,7 +1,7 @@
/*
* Platform abstraction layer
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/platform_util.c b/thirdparty/mbedtls/library/platform_util.c
index c31c173c89..3ba2aead12 100644
--- a/thirdparty/mbedtls/library/platform_util.c
+++ b/thirdparty/mbedtls/library/platform_util.c
@@ -2,7 +2,7 @@
* Common and shared functions used by multiple modules in the Mbed TLS
* library.
*
- * Copyright (C) 2018, Arm Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -43,8 +43,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of Mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c
index 295997f2bc..5b023f04e4 100644
--- a/thirdparty/mbedtls/library/poly1305.c
+++ b/thirdparty/mbedtls/library/poly1305.c
@@ -3,7 +3,7 @@
*
* \brief Poly1305 authentication algorithm.
*
- * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -44,8 +44,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c
index 721db1efe4..0b6efcb574 100644
--- a/thirdparty/mbedtls/library/ripemd160.c
+++ b/thirdparty/mbedtls/library/ripemd160.c
@@ -1,7 +1,7 @@
/*
* RIPE MD-160 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c
index af1cef6515..42becbf17b 100644
--- a/thirdparty/mbedtls/library/rsa.c
+++ b/thirdparty/mbedtls/library/rsa.c
@@ -1,7 +1,7 @@
/*
* The RSA public-key cryptosystem
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
@@ -83,7 +81,7 @@
#include "mbedtls/md.h"
#endif
-#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
+#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
#include <stdlib.h>
#endif
@@ -808,6 +806,9 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret, count = 0;
+ mbedtls_mpi R;
+
+ mbedtls_mpi_init( &R );
if( ctx->Vf.p != NULL )
{
@@ -823,18 +824,41 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
/* Unblinding value: Vf = random number, invertible mod N */
do {
if( count++ > 10 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED );
+ {
+ ret = MBEDTLS_ERR_RSA_RNG_FAILED;
+ goto cleanup;
+ }
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
- } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
- /* Blinding value: Vi = Vf^(-e) mod N */
- MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+ /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
+
+ /* At this point, Vi is invertible mod N if and only if both Vf and R
+ * are invertible mod N. If one of them isn't, we don't need to know
+ * which one, we just loop and choose new values for both of them.
+ * (Each iteration succeeds with overwhelming probability.) */
+ ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
+ if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+ continue;
+ if( ret != 0 )
+ goto cleanup;
+
+ /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
+ } while( 0 );
+
+ /* Blinding value: Vi = Vf^(-e) mod N
+ * (Vi already contains Vf^-1 at this point) */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
cleanup:
+ mbedtls_mpi_free( &R );
+
return( ret );
}
@@ -2590,7 +2614,7 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
#if defined(MBEDTLS_PKCS1_V15)
static int myrand( void *rng_state, unsigned char *output, size_t len )
{
-#if !defined(__OpenBSD__)
+#if !defined(__OpenBSD__) && !defined(__NetBSD__)
size_t i;
if( rng_state != NULL )
@@ -2603,7 +2627,7 @@ static int myrand( void *rng_state, unsigned char *output, size_t len )
rng_state = NULL;
arc4random_buf( output, len );
-#endif /* !OpenBSD */
+#endif /* !OpenBSD && !NetBSD */
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/rsa_internal.c b/thirdparty/mbedtls/library/rsa_internal.c
index 4db49aa578..4d94ca685a 100644
--- a/thirdparty/mbedtls/library/rsa_internal.c
+++ b/thirdparty/mbedtls/library/rsa_internal.c
@@ -1,7 +1,7 @@
/*
* Helper functions for the RSA module
*
- * Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -43,8 +43,6 @@
*
* **********
*
- * This file is part of mbed TLS (https://tls.mbed.org)
- *
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c
index 1cffc75f8c..8682abd740 100644
--- a/thirdparty/mbedtls/library/sha1.c
+++ b/thirdparty/mbedtls/library/sha1.c
@@ -1,7 +1,7 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-1 standard was published by NIST in 1993.
diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c
index d4dd4859a6..5169584b68 100644
--- a/thirdparty/mbedtls/library/sha256.c
+++ b/thirdparty/mbedtls/library/sha256.c
@@ -1,7 +1,7 @@
/*
* FIPS-180-2 compliant SHA-256 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c
index fdcf360d3f..36d5d96146 100644
--- a/thirdparty/mbedtls/library/sha512.c
+++ b/thirdparty/mbedtls/library/sha512.c
@@ -1,7 +1,7 @@
/*
* FIPS-180-2 compliant SHA-384/512 implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
diff --git a/thirdparty/mbedtls/library/ssl_cache.c b/thirdparty/mbedtls/library/ssl_cache.c
index 3cbfeb740a..1d2558a189 100644
--- a/thirdparty/mbedtls/library/ssl_cache.c
+++ b/thirdparty/mbedtls/library/ssl_cache.c
@@ -1,7 +1,7 @@
/*
* SSL session cache implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* These session callbacks use a simple chained list
diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c
index de566ebca9..090040e9ab 100644
--- a/thirdparty/mbedtls/library/ssl_ciphersuites.c
+++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c
@@ -3,7 +3,7 @@
*
* \brief SSL ciphersuites for mbed TLS
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -44,8 +44,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index 9fb2eceb22..bd7f28134d 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 client-side functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c
index 15a3173773..04565e0b79 100644
--- a/thirdparty/mbedtls/library/ssl_cookie.c
+++ b/thirdparty/mbedtls/library/ssl_cookie.c
@@ -1,7 +1,7 @@
/*
* DTLS cookie callbacks implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* These session callbacks use a simple chained list
diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c
index 2c31a8ac54..97b778452c 100644
--- a/thirdparty/mbedtls/library/ssl_srv.c
+++ b/thirdparty/mbedtls/library/ssl_srv.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 server-side functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c
index 4a091bb640..bbde8e4ceb 100644
--- a/thirdparty/mbedtls/library/ssl_ticket.c
+++ b/thirdparty/mbedtls/library/ssl_ticket.c
@@ -1,7 +1,7 @@
/*
* TLS server tickets callbacks implementation
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index a40b46a1c0..2471600c9a 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -1,7 +1,7 @@
/*
* SSLv3/TLSv1 shared functions
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The SSL 3.0 specification was drafted by Netscape in 1996,
@@ -1433,32 +1431,10 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx,
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
- ( defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) )
+ defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
#define SSL_SOME_MODES_USE_MAC
#endif
-/* The function below is only used in the Lucky 13 counter-measure in
- * ssl_decrypt_buf(). These are the defines that guard the call site. */
-#if defined(SSL_SOME_MODES_USE_MAC) && \
- ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2) )
-/* This function makes sure every byte in the memory region is accessed
- * (in ascending addresses order) */
-static void ssl_read_memory( unsigned char *p, size_t len )
-{
- unsigned char acc = 0;
- volatile unsigned char force;
-
- for( ; len != 0; p++, len-- )
- acc ^= *p;
-
- force = acc;
- (void) force;
-}
-#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
-
/*
* Encryption/decryption functions
*/
@@ -1669,8 +1645,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
if( mode == MBEDTLS_MODE_CBC )
{
int ret;
@@ -1789,8 +1764,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
}
else
-#endif /* MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -1808,6 +1782,156 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
return( 0 );
}
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+/*
+ * Constant-flow conditional memcpy:
+ * - if c1 == c2, equivalent to memcpy(dst, src, len),
+ * - otherwise, a no-op,
+ * but with execution flow independent of the values of c1 and c2.
+ *
+ * Use only bit operations to avoid branches that could be used by some
+ * compilers on some platforms to translate comparison operators.
+ */
+static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
+ const unsigned char *src,
+ size_t len,
+ size_t c1, size_t c2 )
+{
+ /* diff = 0 if c1 == c2, non-zero otherwise */
+ const size_t diff = c1 ^ c2;
+
+ /* MSVC has a warning about unary minus on unsigned integer types,
+ * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+ /* diff_msb's most significant bit is equal to c1 != c2 */
+ const size_t diff_msb = ( diff | -diff );
+
+ /* diff1 = c1 != c2 */
+ const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+ /* mask = c1 != c2 ? 0xff : 0x00 */
+ const unsigned char mask = (unsigned char) -diff1;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+ /* dst[i] = c1 != c2 ? dst[i] : src[i] */
+ size_t i;
+ for( i = 0; i < len; i++ )
+ dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask );
+}
+
+/*
+ * Compute HMAC of variable-length data with constant flow.
+ *
+ * Only works with MD-5, SHA-1, SHA-256 and SHA-384.
+ * (Otherwise, computation of block_size needs to be adapted.)
+ */
+int mbedtls_ssl_cf_hmac(
+ mbedtls_md_context_t *ctx,
+ const unsigned char *add_data, size_t add_data_len,
+ const unsigned char *data, size_t data_len_secret,
+ size_t min_data_len, size_t max_data_len,
+ unsigned char *output )
+{
+ /*
+ * This function breaks the HMAC abstraction and uses the md_clone()
+ * extension to the MD API in order to get constant-flow behaviour.
+ *
+ * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
+ * concatenation, and okey/ikey are the XOR of the key with some fixed bit
+ * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
+ *
+ * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
+ * minlen, then cloning the context, and for each byte up to maxlen
+ * finishing up the hash computation, keeping only the correct result.
+ *
+ * Then we only need to compute HASH(okey + inner_hash) and we're done.
+ */
+ const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
+ /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
+ * all of which have the same block size except SHA-384. */
+ const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
+ const unsigned char * const ikey = ctx->hmac_ctx;
+ const unsigned char * const okey = ikey + block_size;
+ const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
+
+ unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
+ mbedtls_md_context_t aux;
+ size_t offset;
+ int ret;
+
+ mbedtls_md_init( &aux );
+
+#define MD_CHK( func_call ) \
+ do { \
+ ret = (func_call); \
+ if( ret != 0 ) \
+ goto cleanup; \
+ } while( 0 )
+
+ MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
+
+ /* After hmac_start() of hmac_reset(), ikey has already been hashed,
+ * so we can start directly with the message */
+ MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
+ MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
+
+ /* For each possible length, compute the hash up to that point */
+ for( offset = min_data_len; offset <= max_data_len; offset++ )
+ {
+ MD_CHK( mbedtls_md_clone( &aux, ctx ) );
+ MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
+ /* Keep only the correct inner_hash in the output buffer */
+ mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size,
+ offset, data_len_secret );
+
+ if( offset < max_data_len )
+ MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
+ }
+
+ /* Now compute HASH(okey + inner_hash) */
+ MD_CHK( mbedtls_md_starts( ctx ) );
+ MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
+ MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
+ MD_CHK( mbedtls_md_finish( ctx, output ) );
+
+ /* Done, get ready for next time */
+ MD_CHK( mbedtls_md_hmac_reset( ctx ) );
+
+#undef MD_CHK
+
+cleanup:
+ mbedtls_md_free( &aux );
+ return( ret );
+}
+
+/*
+ * Constant-flow memcpy from variable position in buffer.
+ * - functionally equivalent to memcpy(dst, src + offset_secret, len)
+ * - but with execution flow independent from the value of offset_secret.
+ */
+void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
+ const unsigned char *src_base,
+ size_t offset_secret,
+ size_t offset_min, size_t offset_max,
+ size_t len )
+{
+ size_t offset;
+
+ for( offset = offset_min; offset <= offset_max; offset++ )
+ {
+ mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len,
+ offset, offset_secret );
+ }
+}
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
{
mbedtls_cipher_mode_t mode;
@@ -1962,8 +2086,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_CIPHER_MODE_CBC) && \
- ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
if( mode == MBEDTLS_MODE_CBC )
{
/*
@@ -2176,8 +2299,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
ssl->in_msglen -= padlen;
}
else
-#endif /* MBEDTLS_CIPHER_MODE_CBC &&
- ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -2196,6 +2318,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
if( auth_done == 0 )
{
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+ unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
ssl->in_msglen -= ssl->transform_in->maclen;
@@ -2210,6 +2333,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
ssl->in_msg, ssl->in_msglen,
ssl->in_ctr, ssl->in_msgtype,
mac_expect );
+ memcpy( mac_peer, ssl->in_msg + ssl->in_msglen,
+ ssl->transform_in->maclen );
}
else
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
@@ -2217,34 +2342,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
{
- /*
- * Process MAC and always update for padlen afterwards to make
- * total time independent of padlen.
- *
- * Known timing attacks:
- * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
- *
- * To compensate for different timings for the MAC calculation
- * depending on how much padding was removed (which is determined
- * by padlen), process extra_run more blocks through the hash
- * function.
- *
- * The formula in the paper is
- * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
- * where L1 is the size of the header plus the decrypted message
- * plus CBC padding and L2 is the size of the header plus the
- * decrypted message. This is for an underlying hash function
- * with 64-byte blocks.
- * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
- * correctly. We round down instead of up, so -56 is the correct
- * value for our calculations instead of -55.
- *
- * Repeat the formula rather than defining a block_size variable.
- * This avoids requiring division by a variable at runtime
- * (which would be marginally less efficient and would require
- * linking an extra division function in some builds).
- */
- size_t j, extra_run = 0;
+ int ret;
+ unsigned char add_data[13];
/*
* The next two sizes are the minimum and maximum values of
@@ -2259,66 +2358,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
const size_t max_len = ssl->in_msglen + padlen;
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
- switch( ssl->transform_in->ciphersuite_info->mac )
- {
-#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
- defined(MBEDTLS_SHA256_C)
- case MBEDTLS_MD_MD5:
- case MBEDTLS_MD_SHA1:
- case MBEDTLS_MD_SHA256:
- /* 8 bytes of message size, 64-byte compression blocks */
- extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
- ( 13 + ssl->in_msglen + 8 ) / 64;
- break;
-#endif
-#if defined(MBEDTLS_SHA512_C)
- case MBEDTLS_MD_SHA384:
- /* 16 bytes of message size, 128-byte compression blocks */
- extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 -
- ( 13 + ssl->in_msglen + 16 ) / 128;
- break;
-#endif
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- extra_run &= correct * 0xFF;
-
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
- mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
- ssl->in_msglen );
- /* Make sure we access everything even when padlen > 0. This
- * makes the synchronisation requirements for just-in-time
- * Prime+Probe attacks much tighter and hopefully impractical. */
- ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen );
- mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
+ memcpy( add_data + 0, ssl->in_ctr, 8 );
+ memcpy( add_data + 8, ssl->in_hdr, 3 );
+ memcpy( add_data + 11, ssl->in_len, 2 );
- /* Dummy calls to compression function.
- * Call mbedtls_md_process at least once due to cache attacks
- * that observe whether md_process() was called of not.
- * Respect the usual start-(process|update)-finish sequence for
- * the sake of hardware accelerators that might require it. */
- mbedtls_md_starts( &ssl->transform_in->md_ctx_dec );
- for( j = 0; j < extra_run + 1; j++ )
- mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
+ ret = mbedtls_ssl_cf_hmac( &ssl->transform_in->md_ctx_dec,
+ add_data, sizeof( add_data ),
+ ssl->in_msg, ssl->in_msglen,
+ min_len, max_len,
+ mac_expect );
+ if( ret != 0 )
{
- /* The switch statement above already checks that we're using
- * one of MD-5, SHA-1, SHA-256 or SHA-384. */
- unsigned char tmp[384 / 8];
- mbedtls_md_finish( &ssl->transform_in->md_ctx_dec, tmp );
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
+ return( ret );
}
- mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
-
- /* Make sure we access all the memory that could contain the MAC,
- * before we check it in the next code block. This makes the
- * synchronisation requirements for just-in-time Prime+Probe
- * attacks much tighter and hopefully impractical. */
- ssl_read_memory( ssl->in_msg + min_len,
- max_len - min_len + ssl->transform_in->maclen );
+ mbedtls_ssl_cf_memcpy_offset( mac_peer, ssl->in_msg,
+ ssl->in_msglen,
+ min_len, max_len,
+ ssl->transform_in->maclen );
}
else
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
@@ -2330,11 +2388,10 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_DEBUG_ALL)
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
- ssl->transform_in->maclen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, ssl->transform_in->maclen );
#endif
- if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
+ if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
ssl->transform_in->maclen ) != 0 )
{
#if defined(MBEDTLS_SSL_DEBUG_ALL)
@@ -2762,7 +2819,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
if( ret < 0 )
return( ret );
- if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+ if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "f_recv returned %d bytes but only %lu were requested",
@@ -2816,7 +2873,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
if( ret <= 0 )
return( ret );
- if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+ if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "f_send returned %d bytes but only %lu bytes were sent",
@@ -8596,6 +8653,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
memcpy( buf, ssl->in_offt, n );
ssl->in_msglen -= n;
+ /* Zeroising the plaintext buffer to erase unused application data
+ from the memory. */
+ mbedtls_platform_zeroize( ssl->in_offt, n );
+
if( ssl->in_msglen == 0 )
{
/* all bytes consumed */
diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c
index 144fe5d46c..61c4b94041 100644
--- a/thirdparty/mbedtls/library/threading.c
+++ b/thirdparty/mbedtls/library/threading.c
@@ -1,7 +1,7 @@
/*
* Threading abstraction layer
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c
index a4beff35a9..50a22165a6 100644
--- a/thirdparty/mbedtls/library/timing.c
+++ b/thirdparty/mbedtls/library/timing.c
@@ -1,7 +1,7 @@
/*
* Portable interface to the CPU cycle counter
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/version.c b/thirdparty/mbedtls/library/version.c
index bdba12f613..5733288f62 100644
--- a/thirdparty/mbedtls/library/version.c
+++ b/thirdparty/mbedtls/library/version.c
@@ -1,7 +1,7 @@
/*
* Version information
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c
index 51662bfd21..cbf38dc2c2 100644
--- a/thirdparty/mbedtls/library/version_features.c
+++ b/thirdparty/mbedtls/library/version_features.c
@@ -1,7 +1,7 @@
/*
* Version feature information
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
@@ -279,6 +277,12 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
"MBEDTLS_ECP_NORMALIZE_MXZ_ALT",
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+ "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN",
+#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
+#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
+ "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND",
+#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
"MBEDTLS_TEST_NULL_ENTROPY",
#endif /* MBEDTLS_TEST_NULL_ENTROPY */
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index 63ceaf9f4d..0c820eca90 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -1,7 +1,7 @@
/*
* X.509 common functions for parsing and verification
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
diff --git a/thirdparty/mbedtls/library/x509_create.c b/thirdparty/mbedtls/library/x509_create.c
index 75de91f6c8..0dbd679a93 100644
--- a/thirdparty/mbedtls/library/x509_create.c
+++ b/thirdparty/mbedtls/library/x509_create.c
@@ -1,7 +1,7 @@
/*
* X.509 base functions for creating certificates / CSRs
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c
index 94c0c01afe..dba71fad58 100644
--- a/thirdparty/mbedtls/library/x509_crl.c
+++ b/thirdparty/mbedtls/library/x509_crl.c
@@ -1,7 +1,7 @@
/*
* X.509 Certidicate Revocation List (CRL) parsing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -285,13 +283,13 @@ static int x509_get_entries( unsigned char **p,
size_t len2;
const unsigned char *end2;
+ cur_entry->raw.tag = **p;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
{
return( ret );
}
- cur_entry->raw.tag = **p;
cur_entry->raw.p = *p;
cur_entry->raw.len = len2;
end2 = *p + len2;
diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c
index 7d01585472..de40eaaf58 100644
--- a/thirdparty/mbedtls/library/x509_crt.c
+++ b/thirdparty/mbedtls/library/x509_crt.c
@@ -1,7 +1,7 @@
/*
* X.509 certificate parsing and verification
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -1846,8 +1844,7 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509
if( crt->serial.len == cur->serial.len &&
memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
{
- if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
- return( 1 );
+ return( 1 );
}
cur = cur->next;
diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c
index 5045c10830..663047d516 100644
--- a/thirdparty/mbedtls/library/x509_csr.c
+++ b/thirdparty/mbedtls/library/x509_csr.c
@@ -1,7 +1,7 @@
/*
* X.509 Certificate Signing Request (CSR) parsing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c
index 0fc94fed2e..5462e83fe0 100644
--- a/thirdparty/mbedtls/library/x509write_crt.c
+++ b/thirdparty/mbedtls/library/x509write_crt.c
@@ -1,7 +1,7 @@
/*
* X.509 certificate writing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* References:
@@ -101,39 +99,44 @@ void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
}
-void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
+void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx,
+ int version )
{
ctx->version = version;
}
-void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg )
+void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx,
+ mbedtls_md_type_t md_alg )
{
ctx->md_alg = md_alg;
}
-void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
+void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx,
+ mbedtls_pk_context *key )
{
ctx->subject_key = key;
}
-void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
+void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx,
+ mbedtls_pk_context *key )
{
ctx->issuer_key = key;
}
int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
- const char *subject_name )
+ const char *subject_name )
{
return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
}
int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
- const char *issuer_name )
+ const char *issuer_name )
{
return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name );
}
-int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial )
+int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx,
+ const mbedtls_mpi *serial )
{
int ret;
@@ -143,8 +146,9 @@ int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls
return( 0 );
}
-int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
- const char *not_after )
+int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx,
+ const char *not_before,
+ const char *not_after )
{
if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 )
@@ -164,12 +168,12 @@ int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
int critical,
const unsigned char *val, size_t val_len )
{
- return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
- critical, val, val_len );
+ return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
+ critical, val, val_len ) );
}
int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
- int is_ca, int max_pathlen )
+ int is_ca, int max_pathlen )
{
int ret;
unsigned char buf[9];
@@ -185,18 +189,21 @@ int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
{
if( max_pathlen >= 0 )
{
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf,
+ max_pathlen ) );
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
}
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) );
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
- 0, buf + sizeof(buf) - len, len );
+ return(
+ mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
+ 0, buf + sizeof(buf) - len, len ) );
}
#if defined(MBEDTLS_SHA1_C)
@@ -208,7 +215,8 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct
size_t len = 0;
memset( buf, 0, sizeof(buf) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
buf + sizeof( buf ) - 20 );
@@ -218,11 +226,13 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct
len = 20;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
- 0, buf + sizeof(buf) - len, len );
+ return mbedtls_x509write_crt_set_extension( ctx,
+ MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
+ 0, buf + sizeof(buf) - len, len );
}
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
@@ -233,7 +243,8 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
size_t len = 0;
memset( buf, 0, sizeof(buf) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
buf + sizeof( buf ) - 20 );
@@ -243,15 +254,19 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
len = 20;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
-
- return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
- 0, buf + sizeof( buf ) - len, len );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE ) );
+
+ return mbedtls_x509write_crt_set_extension(
+ ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
+ 0, buf + sizeof( buf ) - len, len );
}
#endif /* MBEDTLS_SHA1_C */
@@ -298,8 +313,8 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
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, c, (size_t)ret );
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
+ 1, c, (size_t)ret );
if( ret != 0 )
return( ret );
@@ -325,8 +340,8 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
return( ret );
ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
- 0, c, (size_t)ret );
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
+ 0, c, (size_t)ret );
if( ret != 0 )
return( ret );
@@ -348,7 +363,8 @@ static int x509_write_time( unsigned char **p, unsigned char *start,
(const unsigned char *) t + 2,
size - 2 ) );
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_UTC_TIME ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+ MBEDTLS_ASN1_UTC_TIME ) );
}
else
{
@@ -356,15 +372,17 @@ static int x509_write_time( unsigned char **p, unsigned char *start,
(const unsigned char *) t,
size ) );
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_GENERALIZED_TIME ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+ MBEDTLS_ASN1_GENERALIZED_TIME ) );
}
return( (int) len );
}
-int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
+int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx,
+ unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
{
int ret;
const char *sig_oid;
@@ -372,15 +390,14 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
unsigned char *c, *c2;
unsigned char hash[64];
unsigned char sig[SIGNATURE_MAX_SIZE];
- unsigned char tmp_buf[2048];
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
/*
- * Prepare data to be signed in tmp_buf
+ * Prepare data to be signed at the end of the target buffer
*/
- c = tmp_buf + sizeof( tmp_buf );
+ c = buf + size;
/* Signature algorithm needed in TBS, and later for actual signature */
@@ -406,27 +423,36 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
/* Only for v3 */
if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 )
{
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_x509_write_extensions( &c,
+ buf, ctx->extensions ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
}
/*
* SubjectPublicKeyInfo
*/
- MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key,
- tmp_buf, c - tmp_buf ) );
+ MBEDTLS_ASN1_CHK_ADD( pub_len,
+ mbedtls_pk_write_pubkey_der( ctx->subject_key,
+ buf, c - buf ) );
c -= pub_len;
len += pub_len;
/*
* Subject ::= Name
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_x509_write_names( &c, buf,
+ ctx->subject ) );
/*
* Validity ::= SEQUENCE {
@@ -435,32 +461,39 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
*/
sub_len = 0;
- MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
- MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
+ MBEDTLS_ASN1_CHK_ADD( sub_len,
+ x509_write_time( &c, buf, ctx->not_after,
+ MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
- MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
- MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
+ MBEDTLS_ASN1_CHK_ADD( sub_len,
+ x509_write_time( &c, buf, ctx->not_before,
+ MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
len += sub_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE ) );
/*
* Issuer ::= Name
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf,
+ ctx->issuer ) );
/*
* Signature ::= AlgorithmIdentifier
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf,
- sig_oid, strlen( sig_oid ), 0 ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_algorithm_identifier( &c, buf,
+ sig_oid, strlen( sig_oid ), 0 ) );
/*
* Serial ::= INTEGER
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf,
+ &ctx->serial ) );
/*
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
@@ -470,48 +503,67 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 )
{
sub_len = 0;
- MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
+ MBEDTLS_ASN1_CHK_ADD( sub_len,
+ mbedtls_asn1_write_int( &c, buf, ctx->version ) );
len += sub_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_len( &c, buf, sub_len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
}
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE ) );
/*
* Make signature
*/
+
+ /* Compute hash of CRT. */
if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c,
len, hash ) ) != 0 )
{
return( ret );
}
- if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
- f_rng, p_rng ) ) != 0 )
+ if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg,
+ hash, 0, sig, &sig_len,
+ f_rng, p_rng ) ) != 0 )
{
return( ret );
}
- /*
- * Write data to output buffer
- */
+ /* Move CRT to the front of the buffer to have space
+ * for the signature. */
+ memmove( buf, c, len );
+ c = buf + len;
+
+ /* Add signature at the end of the buffer,
+ * making sure that it doesn't underflow
+ * into the CRT buffer. */
c2 = buf + size;
- MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
+ MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c,
sig_oid, sig_oid_len, sig, sig_len ) );
- if( len > (size_t)( c2 - buf ) )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ /*
+ * Memory layout after this step:
+ *
+ * buf c=buf+len c2 buf+size
+ * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm]
+ */
- c2 -= len;
- memcpy( c2, c, len );
+ /* Move raw CRT to just before the signature. */
+ c = c2 - len;
+ memmove( c, buf, len );
len += sig_and_oid_len;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) );
return( (int) len );
@@ -521,23 +573,23 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf,
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
#if defined(MBEDTLS_PEM_WRITE_C)
-int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
+int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt,
+ unsigned char *buf, size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
{
int ret;
- unsigned char output_buf[4096];
- size_t olen = 0;
+ size_t olen;
- if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf),
+ if( ( ret = mbedtls_x509write_crt_der( crt, buf, size,
f_rng, p_rng ) ) < 0 )
{
return( ret );
}
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
- output_buf + sizeof(output_buf) - ret,
- ret, buf, size, &olen ) ) != 0 )
+ buf + size - ret, ret,
+ buf, size, &olen ) ) != 0 )
{
return( ret );
}
diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c
index d1b0716c96..60cf12379f 100644
--- a/thirdparty/mbedtls/library/x509write_csr.c
+++ b/thirdparty/mbedtls/library/x509write_csr.c
@@ -1,7 +1,7 @@
/*
* X.509 Certificate Signing Request writing
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* References:
@@ -81,6 +79,14 @@
#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
#endif
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
{
memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
@@ -187,71 +193,85 @@ int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
return( 0 );
}
-int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
+static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
+ unsigned char *buf,
+ size_t size,
+ unsigned char *sig,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
{
int ret;
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
unsigned char hash[64];
- unsigned char sig[SIGNATURE_MAX_SIZE];
- unsigned char tmp_buf[2048];
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
- /*
- * Prepare data to be signed in tmp_buf
- */
- c = tmp_buf + sizeof( tmp_buf );
+ /* Write the CSR backwards starting from the end of buf */
+ c = buf + size;
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, buf,
+ ctx->extensions ) );
if( len )
{
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
-
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SET ) );
-
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
- MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
-
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) );
+
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_oid(
+ &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
+ MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
+
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
}
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
- tmp_buf, c - tmp_buf ) );
+ buf, c - buf ) );
c -= pub_len;
len += pub_len;
/*
* Subject ::= Name
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf,
+ ctx->subject ) );
/*
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
*/
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
/*
- * Prepare signature
+ * Sign the written CSR data into the sig buffer
+ * Note: hash errors can happen only after an internal error
*/
ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
if( ret != 0 )
@@ -271,32 +291,68 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s
return( MBEDTLS_ERR_X509_INVALID_ALG );
if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
- &sig_oid, &sig_oid_len ) ) != 0 )
+ &sig_oid, &sig_oid_len ) ) != 0 )
{
return( ret );
}
/*
- * Write data to output buffer
+ * Move the written CSR data to the start of buf to create space for
+ * writing the signature into buf.
*/
- c2 = buf + size;
- MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
- sig_oid, sig_oid_len, sig, sig_len ) );
+ memmove( buf, c, len );
- if( len > (size_t)( c2 - buf ) )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ /*
+ * Write sig and its OID into buf backwards from the end of buf.
+ * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len
+ * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed.
+ */
+ c2 = buf + size;
+ MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len,
+ mbedtls_x509_write_sig( &c2, buf + len, sig_oid, sig_oid_len,
+ sig, sig_len ) );
+ /*
+ * Compact the space between the CSR data and signature by moving the
+ * CSR data to the start of the signature.
+ */
c2 -= len;
- memcpy( c2, c, len );
+ memmove( c2, buf, len );
+ /* ASN encode the total size and tag the CSR data with it. */
len += sig_and_oid_len;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE ) );
+ MBEDTLS_ASN1_CHK_ADD( len,
+ mbedtls_asn1_write_tag(
+ &c2, buf,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+ /* Zero the unused bytes at the start of buf */
+ memset( buf, 0, c2 - buf);
return( (int) len );
}
+int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf,
+ size_t size,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ int ret;
+ unsigned char *sig;
+
+ if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL )
+ {
+ return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+ }
+
+ ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng );
+
+ mbedtls_free( sig );
+
+ return( ret );
+}
+
#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
diff --git a/thirdparty/mbedtls/library/xtea.c b/thirdparty/mbedtls/library/xtea.c
index 26ec5de5a9..4e62817579 100644
--- a/thirdparty/mbedtls/library/xtea.c
+++ b/thirdparty/mbedtls/library/xtea.c
@@ -1,7 +1,7 @@
/*
* An 32-bit implementation of the XTEA algorithm
*
- * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*
* This file is provided under the Apache License 2.0, or the
@@ -42,8 +42,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* **********
- *
- * This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
diff --git a/thirdparty/tinyexr/tinyexr.cc b/thirdparty/tinyexr/tinyexr.cc
index 969a6d505d..fef8f66c98 100644
--- a/thirdparty/tinyexr/tinyexr.cc
+++ b/thirdparty/tinyexr/tinyexr.cc
@@ -1,2 +1,8 @@
+#if defined(_WIN32)
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#endif
+
#define TINYEXR_IMPLEMENTATION
#include "tinyexr.h"
diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h
index 7e8956f7d3..a3e7b23161 100644
--- a/thirdparty/tinyexr/tinyexr.h
+++ b/thirdparty/tinyexr/tinyexr.h
@@ -1,5 +1,7 @@
+#ifndef TINYEXR_H_
+#define TINYEXR_H_
/*
-Copyright (c) 2014 - 2019, Syoyo Fujita and many contributors.
+Copyright (c) 2014 - 2020, Syoyo Fujita and many contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -63,9 +65,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// End of OpenEXR license -------------------------------------------------
-#ifndef TINYEXR_H_
-#define TINYEXR_H_
-
//
//
// Do this:
@@ -198,11 +197,18 @@ typedef struct _EXRTile {
unsigned char **images; // image[channels][pixels]
} EXRTile;
+typedef struct _EXRBox2i {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} EXRBox2i;
+
typedef struct _EXRHeader {
float pixel_aspect_ratio;
int line_order;
- int data_window[4];
- int display_window[4];
+ EXRBox2i data_window;
+ EXRBox2i display_window;
float screen_window_center[2];
float screen_window_width;
@@ -287,26 +293,29 @@ typedef struct _DeepImage {
extern int LoadEXR(float **out_rgba, int *width, int *height,
const char *filename, const char **err);
-// Loads single-frame OpenEXR image by specifing layer name. Assume EXR image contains A(single channel
-// alpha) or RGB(A) channels.
-// Application must free image data as returned by `out_rgba`
-// Result image format is: float x RGBA x width x hight
-// Returns negative value and may set error string in `err` when there's an
-// error
-// When the specified layer name is not found in the EXR file, the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
+// Loads single-frame OpenEXR image by specifying layer name. Assume EXR image
+// contains A(single channel alpha) or RGB(A) channels. Application must free
+// image data as returned by `out_rgba` Result image format is: float x RGBA x
+// width x hight Returns negative value and may set error string in `err` when
+// there's an error When the specified layer name is not found in the EXR file,
+// the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
- const char *filename, const char *layer_name, const char **err);
+ const char *filename, const char *layer_name,
+ const char **err);
//
// Get layer infos from EXR file.
//
-// @param[out] layer_names List of layer names. Application must free memory after using this.
+// @param[out] layer_names List of layer names. Application must free memory
+// after using this.
// @param[out] num_layers The number of layers
-// @param[out] err Error string(wll be filled when the function returns error code). Free it using FreeEXRErrorMessage after using this value.
+// @param[out] err Error string(will be filled when the function returns error
+// code). Free it using FreeEXRErrorMessage after using this value.
//
// @return TINYEXR_SUCCEES upon success.
//
-extern int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err);
+extern int EXRLayers(const char *filename, const char **layer_names[],
+ int *num_layers, const char **err);
// @deprecated { to be removed. }
// Simple wrapper API for ParseEXRHeaderFromFile.
@@ -336,13 +345,13 @@ extern void InitEXRHeader(EXRHeader *exr_header);
// Initialize EXRImage struct
extern void InitEXRImage(EXRImage *exr_image);
-// Free's internal data of EXRHeader struct
+// Frees internal data of EXRHeader struct
extern int FreeEXRHeader(EXRHeader *exr_header);
-// Free's internal data of EXRImage struct
+// Frees internal data of EXRImage struct
extern int FreeEXRImage(EXRImage *exr_image);
-// Free's error message
+// Frees error message
extern void FreeEXRErrorMessage(const char *msg);
// Parse EXR version header of a file.
@@ -497,8 +506,17 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#endif // TINYEXR_H_
#ifdef TINYEXR_IMPLEMENTATION
-#ifndef TINYEXR_IMPLEMENTATION_DEIFNED
-#define TINYEXR_IMPLEMENTATION_DEIFNED
+#ifndef TINYEXR_IMPLEMENTATION_DEFINED
+#define TINYEXR_IMPLEMENTATION_DEFINED
+
+#ifdef _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h> // for UTF-8
+
+#endif
#include <algorithm>
#include <cassert>
@@ -536,7 +554,18 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#endif
#if TINYEXR_USE_ZFP
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#endif
+
#include "zfp.h"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
#endif
namespace tinyexr {
@@ -619,7 +648,7 @@ namespace miniz {
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug
(thanks kahmyong.moon@hp.com) which could cause locate files to not find
files. This bug
- would only have occured in earlier versions if you explicitly used this
+ would only have occurred in earlier versions if you explicitly used this
flag, OR if you used mz_zip_extract_archive_file_to_heap() or
mz_zip_add_mem_to_archive_file_in_place()
(which used this flag). If you can't switch to v1.15 but want to fix
@@ -7002,6 +7031,13 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
// Reuse MINIZ_LITTE_ENDIAN macro
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
+ defined(__i386) || defined(__i486__) || defined(__i486) || \
+ defined(i386) || defined(__ia64__) || defined(__x86_64__)
+// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
+#define MINIZ_X86_OR_X64_CPU 1
+#endif
+
#if defined(__sparcv9)
// Big endian
#else
@@ -7116,6 +7152,36 @@ static void swap4(unsigned int *val) {
#endif
}
+static void swap4(int *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+static void swap4(float *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ float tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
#if 0
static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) {
unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
@@ -7363,7 +7429,7 @@ static void WriteAttributeToMemory(std::vector<unsigned char> *out,
out->insert(out->end(), type, type + strlen(type) + 1);
int outLen = len;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&outLen));
+ tinyexr::swap4(&outLen);
out->insert(out->end(), reinterpret_cast<unsigned char *>(&outLen),
reinterpret_cast<unsigned char *>(&outLen) + sizeof(int));
out->insert(out->end(), data, data + len);
@@ -7379,12 +7445,19 @@ typedef struct {
} ChannelInfo;
typedef struct {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} Box2iInfo;
+
+struct HeaderInfo {
std::vector<tinyexr::ChannelInfo> channels;
std::vector<EXRAttribute> attributes;
- int data_window[4];
+ Box2iInfo data_window;
int line_order;
- int display_window[4];
+ Box2iInfo display_window;
float screen_window_center[2];
float screen_window_width;
float pixel_aspect_ratio;
@@ -7405,15 +7478,15 @@ typedef struct {
channels.clear();
attributes.clear();
- data_window[0] = 0;
- data_window[1] = 0;
- data_window[2] = 0;
- data_window[3] = 0;
+ data_window.min_x = 0;
+ data_window.min_y = 0;
+ data_window.max_x = 0;
+ data_window.max_y = 0;
line_order = 0;
- display_window[0] = 0;
- display_window[1] = 0;
- display_window[2] = 0;
- display_window[3] = 0;
+ display_window.min_x = 0;
+ display_window.min_y = 0;
+ display_window.max_x = 0;
+ display_window.max_y = 0;
screen_window_center[0] = 0.0f;
screen_window_center[1] = 0.0f;
screen_window_width = 0.0f;
@@ -7430,7 +7503,7 @@ typedef struct {
header_len = 0;
compression_type = 0;
}
-} HeaderInfo;
+};
static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
const std::vector<unsigned char> &data) {
@@ -7469,9 +7542,9 @@ static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
memcpy(&info.y_sampling, p, sizeof(int)); // int
p += 4;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.pixel_type));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.x_sampling));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.y_sampling));
+ tinyexr::swap4(&info.pixel_type);
+ tinyexr::swap4(&info.x_sampling);
+ tinyexr::swap4(&info.y_sampling);
channels.push_back(info);
}
@@ -7501,9 +7574,9 @@ static void WriteChannelInfo(std::vector<unsigned char> &data,
int pixel_type = channels[c].pixel_type;
int x_sampling = channels[c].x_sampling;
int y_sampling = channels[c].y_sampling;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&pixel_type));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&x_sampling));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y_sampling));
+ tinyexr::swap4(&pixel_type);
+ tinyexr::swap4(&x_sampling);
+ tinyexr::swap4(&y_sampling);
memcpy(p, &pixel_type, sizeof(int));
p += sizeof(int);
@@ -7712,7 +7785,7 @@ static int rleCompress(int inLength, const char in[], signed char out[]) {
if (runEnd - runStart >= MIN_RUN_LENGTH) {
//
- // Compressable run
+ // Compressible run
//
*outWrite++ = static_cast<char>(runEnd - runStart) - 1;
@@ -8056,7 +8129,7 @@ static void wav2Encode(
int p2 = 2; // == 1 << (level+1)
//
- // Hierachical loop on smaller dimension n
+ // Hierarchical loop on smaller dimension n
//
while (p2 <= n) {
@@ -8287,9 +8360,9 @@ const int HUF_DECMASK = HUF_DECSIZE - 1;
struct HufDec { // short code long code
//-------------------------------
- int len : 8; // code length 0
- int lit : 24; // lit p size
- int *p; // 0 lits
+ unsigned int len : 8; // code length 0
+ unsigned int lit : 24; // lit p size
+ unsigned int *p; // 0 lits
};
inline long long hufLength(long long code) { return code & 63; }
@@ -8745,14 +8818,14 @@ static bool hufBuildDecTable(const long long *hcode, // i : encoding table
pl->lit++;
if (pl->p) {
- int *p = pl->p;
- pl->p = new int[pl->lit];
+ unsigned int *p = pl->p;
+ pl->p = new unsigned int[pl->lit];
for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i];
delete[] p;
} else {
- pl->p = new int[1];
+ pl->p = new unsigned int[1];
}
pl->p[pl->lit - 1] = im;
@@ -9491,35 +9564,48 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
#endif // TINYEXR_USE_PIZ
#if TINYEXR_USE_ZFP
+
struct ZFPCompressionParam {
double rate;
- int precision;
+ unsigned int precision;
+ unsigned int __pad0;
double tolerance;
int type; // TINYEXR_ZFP_COMPRESSIONTYPE_*
+ unsigned int __pad1;
ZFPCompressionParam() {
type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
rate = 2.0;
precision = 0;
- tolerance = 0.0f;
+ tolerance = 0.0;
}
};
-bool FindZFPCompressionParam(ZFPCompressionParam *param,
- const EXRAttribute *attributes,
- int num_attributes) {
+static bool FindZFPCompressionParam(ZFPCompressionParam *param,
+ const EXRAttribute *attributes,
+ int num_attributes, std::string *err) {
bool foundType = false;
for (int i = 0; i < num_attributes; i++) {
- if ((strcmp(attributes[i].name, "zfpCompressionType") == 0) &&
- (attributes[i].size == 1)) {
- param->type = static_cast<int>(attributes[i].value[0]);
-
- foundType = true;
+ if ((strcmp(attributes[i].name, "zfpCompressionType") == 0)) {
+ if (attributes[i].size == 1) {
+ param->type = static_cast<int>(attributes[i].value[0]);
+ foundType = true;
+ break;
+ } else {
+ if (err) {
+ (*err) +=
+ "zfpCompressionType attribute must be uchar(1 byte) type.\n";
+ }
+ return false;
+ }
}
}
if (!foundType) {
+ if (err) {
+ (*err) += "`zfpCompressionType` attribute not found.\n";
+ }
return false;
}
@@ -9531,6 +9617,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionRate` attribute not found.\n";
+ }
+
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) &&
@@ -9539,6 +9630,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionPrecision` attribute not found.\n";
+ }
+
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) &&
@@ -9547,8 +9643,14 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
return true;
}
}
+
+ if (err) {
+ (*err) += "`zfpCompressionTolerance` attribute not found.\n";
+ }
} else {
- assert(0);
+ if (err) {
+ (*err) += "Unknown value specified for `zfpCompressionType`.\n";
+ }
}
return false;
@@ -9556,10 +9658,11 @@ bool FindZFPCompressionParam(ZFPCompressionParam *param,
// Assume pixel format is FLOAT for all channels.
static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
- int num_channels, const unsigned char *src,
+ size_t num_channels, const unsigned char *src,
unsigned long src_size,
const ZFPCompressionParam &param) {
- size_t uncompressed_size = dst_width * dst_num_lines * num_channels;
+ size_t uncompressed_size =
+ size_t(dst_width) * size_t(dst_num_lines) * num_channels;
if (uncompressed_size == src_size) {
// Data is not compressed(Issue 40).
@@ -9572,22 +9675,24 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
assert((dst_width % 4) == 0);
assert((dst_num_lines % 4) == 0);
- if ((dst_width & 3U) || (dst_num_lines & 3U)) {
+ if ((size_t(dst_width) & 3U) || (size_t(dst_num_lines) & 3U)) {
return false;
}
field =
zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)),
- zfp_type_float, dst_width, dst_num_lines * num_channels);
+ zfp_type_float, static_cast<unsigned int>(dst_width),
+ static_cast<unsigned int>(dst_num_lines) *
+ static_cast<unsigned int>(num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
- zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimention */ 2,
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimension */ 2,
/* write random access */ 0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
- zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
- zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
assert(0);
}
@@ -9600,17 +9705,17 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
zfp_stream_set_bit_stream(zfp, stream);
zfp_stream_rewind(zfp);
- size_t image_size = dst_width * dst_num_lines;
+ size_t image_size = size_t(dst_width) * size_t(dst_num_lines);
- for (int c = 0; c < num_channels; c++) {
+ for (size_t c = 0; c < size_t(num_channels); c++) {
// decompress 4x4 pixel block.
- for (int y = 0; y < dst_num_lines; y += 4) {
- for (int x = 0; x < dst_width; x += 4) {
+ for (size_t y = 0; y < size_t(dst_num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(dst_width); x += 4) {
float fblock[16];
zfp_decode_block_float_2(zfp, fblock);
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 4; i++) {
- dst[c * image_size + ((y + j) * dst_width + (x + i))] =
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
+ dst[c * image_size + ((y + j) * size_t(dst_width) + (x + i))] =
fblock[j * 4 + i];
}
}
@@ -9626,31 +9731,33 @@ static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
}
// Assume pixel format is FLOAT for all channels.
-bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
- const float *inPtr, int width, int num_lines, int num_channels,
- const ZFPCompressionParam &param) {
+static bool CompressZfp(std::vector<unsigned char> *outBuf,
+ unsigned int *outSize, const float *inPtr, int width,
+ int num_lines, int num_channels,
+ const ZFPCompressionParam &param) {
zfp_stream *zfp = NULL;
zfp_field *field = NULL;
assert((width % 4) == 0);
assert((num_lines % 4) == 0);
- if ((width & 3U) || (num_lines & 3U)) {
+ if ((size_t(width) & 3U) || (size_t(num_lines) & 3U)) {
return false;
}
// create input array.
field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)),
- zfp_type_float, width, num_lines * num_channels);
+ zfp_type_float, static_cast<unsigned int>(width),
+ static_cast<unsigned int>(num_lines * num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
- zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
- zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
assert(0);
}
@@ -9663,17 +9770,17 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
zfp_stream_set_bit_stream(zfp, stream);
zfp_field_free(field);
- size_t image_size = width * num_lines;
+ size_t image_size = size_t(width) * size_t(num_lines);
- for (int c = 0; c < num_channels; c++) {
+ for (size_t c = 0; c < size_t(num_channels); c++) {
// compress 4x4 pixel block.
- for (int y = 0; y < num_lines; y += 4) {
- for (int x = 0; x < width; x += 4) {
+ for (size_t y = 0; y < size_t(num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(width); x += 4) {
float fblock[16];
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 4; i++) {
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
fblock[j * 4 + i] =
- inPtr[c * image_size + ((y + j) * width + (x + i))];
+ inPtr[c * image_size + ((y + j) * size_t(width) + (x + i))];
}
}
zfp_encode_block_float_2(zfp, fblock);
@@ -9682,7 +9789,7 @@ bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
}
zfp_stream_flush(zfp);
- (*outSize) = zfp_stream_compressed_size(zfp);
+ (*outSize) = static_cast<unsigned int>(zfp_stream_compressed_size(zfp));
zfp_stream_close(zfp);
@@ -10122,8 +10229,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
} else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
#if TINYEXR_USE_ZFP
tinyexr::ZFPCompressionParam zfp_compression_param;
- if (!FindZFPCompressionParam(&zfp_compression_param, attributes,
- num_attributes)) {
+ std::string e;
+ if (!tinyexr::FindZFPCompressionParam(&zfp_compression_param, attributes,
+ int(num_attributes), &e)) {
+ // This code path should not be reachable.
assert(0);
return false;
}
@@ -10323,8 +10432,11 @@ static bool DecodeTiledPixelData(
const EXRAttribute *attributes, size_t num_channels,
const EXRChannelInfo *channels,
const std::vector<size_t> &channel_offset_list) {
- assert(tile_offset_x * tile_size_x < data_width);
- assert(tile_offset_y * tile_size_y < data_height);
+ if (tile_size_x > data_width || tile_size_y > data_height ||
+ tile_size_x * tile_offset_x > data_width ||
+ tile_size_y * tile_offset_y > data_height) {
+ return false;
+ }
// Compute actual image size in a tile.
if ((tile_offset_x + 1) * tile_size_x >= data_width) {
@@ -10418,6 +10530,17 @@ static unsigned char **AllocateImage(int num_channels,
return images;
}
+#ifdef _WIN32
+static inline std::wstring UTF8ToWchar(const std::string &str) {
+ int wstr_size =
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
+ std::wstring wstr(wstr_size, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
+ (int)wstr.size());
+ return wstr;
+}
+#endif
+
static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
const EXRVersion *version, std::string *err,
const unsigned char *buf, size_t size) {
@@ -10457,15 +10580,15 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
bool has_screen_window_center = false;
bool has_screen_window_width = false;
- info->data_window[0] = 0;
- info->data_window[1] = 0;
- info->data_window[2] = 0;
- info->data_window[3] = 0;
+ info->data_window.min_x = 0;
+ info->data_window.min_y = 0;
+ info->data_window.max_x = 0;
+ info->data_window.max_y = 0;
info->line_order = 0; // @fixme
- info->display_window[0] = 0;
- info->display_window[1] = 0;
- info->display_window[2] = 0;
- info->display_window[3] = 0;
+ info->display_window.min_x = 0;
+ info->display_window.min_y = 0;
+ info->display_window.max_x = 0;
+ info->display_window.max_y = 0;
info->screen_window_center[0] = 0.0f;
info->screen_window_center[1] = 0.0f;
info->screen_window_width = -1.0f;
@@ -10515,6 +10638,14 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
tinyexr::swap4(&x_size);
tinyexr::swap4(&y_size);
+ if (x_size > static_cast<unsigned int>(std::numeric_limits<int>::max()) ||
+ y_size > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
+ if (err) {
+ (*err) = "Tile sizes were invalid.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
info->tile_size_x = static_cast<int>(x_size);
info->tile_size_y = static_cast<int>(y_size);
@@ -10586,30 +10717,26 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
} else if (attr_name.compare("dataWindow") == 0) {
if (data.size() >= 16) {
- memcpy(&info->data_window[0], &data.at(0), sizeof(int));
- memcpy(&info->data_window[1], &data.at(4), sizeof(int));
- memcpy(&info->data_window[2], &data.at(8), sizeof(int));
- memcpy(&info->data_window[3], &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[1]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[2]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[3]));
+ memcpy(&info->data_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->data_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->data_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->data_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->data_window.min_x);
+ tinyexr::swap4(&info->data_window.min_y);
+ tinyexr::swap4(&info->data_window.max_x);
+ tinyexr::swap4(&info->data_window.max_y);
has_data_window = true;
}
} else if (attr_name.compare("displayWindow") == 0) {
if (data.size() >= 16) {
- memcpy(&info->display_window[0], &data.at(0), sizeof(int));
- memcpy(&info->display_window[1], &data.at(4), sizeof(int));
- memcpy(&info->display_window[2], &data.at(8), sizeof(int));
- memcpy(&info->display_window[3], &data.at(12), sizeof(int));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[1]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[2]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->display_window[3]));
+ memcpy(&info->display_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->display_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->display_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->display_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->display_window.min_x);
+ tinyexr::swap4(&info->display_window.min_y);
+ tinyexr::swap4(&info->display_window.max_x);
+ tinyexr::swap4(&info->display_window.max_y);
has_display_window = true;
}
@@ -10621,32 +10748,28 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
} else if (attr_name.compare("pixelAspectRatio") == 0) {
if (data.size() >= sizeof(float)) {
memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->pixel_aspect_ratio));
+ tinyexr::swap4(&info->pixel_aspect_ratio);
has_pixel_aspect_ratio = true;
}
} else if (attr_name.compare("screenWindowCenter") == 0) {
if (data.size() >= 8) {
memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float));
memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_center[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_center[1]));
+ tinyexr::swap4(&info->screen_window_center[0]);
+ tinyexr::swap4(&info->screen_window_center[1]);
has_screen_window_center = true;
}
} else if (attr_name.compare("screenWindowWidth") == 0) {
if (data.size() >= sizeof(float)) {
memcpy(&info->screen_window_width, &data.at(0), sizeof(float));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&info->screen_window_width));
+ tinyexr::swap4(&info->screen_window_width);
has_screen_window_width = true;
}
} else if (attr_name.compare("chunkCount") == 0) {
if (data.size() >= sizeof(int)) {
memcpy(&info->chunk_count, &data.at(0), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count));
+ tinyexr::swap4(&info->chunk_count);
}
} else {
// Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES)
@@ -10732,14 +10855,14 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
exr_header->screen_window_center[1] = info.screen_window_center[1];
exr_header->screen_window_width = info.screen_window_width;
exr_header->chunk_count = info.chunk_count;
- exr_header->display_window[0] = info.display_window[0];
- exr_header->display_window[1] = info.display_window[1];
- exr_header->display_window[2] = info.display_window[2];
- exr_header->display_window[3] = info.display_window[3];
- exr_header->data_window[0] = info.data_window[0];
- exr_header->data_window[1] = info.data_window[1];
- exr_header->data_window[2] = info.data_window[2];
- exr_header->data_window[3] = info.data_window[3];
+ exr_header->display_window.min_x = info.display_window.min_x;
+ exr_header->display_window.min_y = info.display_window.min_y;
+ exr_header->display_window.max_x = info.display_window.max_x;
+ exr_header->display_window.max_y = info.display_window.max_y;
+ exr_header->data_window.min_x = info.data_window.min_x;
+ exr_header->data_window.min_y = info.data_window.min_y;
+ exr_header->data_window.max_x = info.data_window.max_x;
+ exr_header->data_window.max_y = info.data_window.max_y;
exr_header->line_order = info.line_order;
exr_header->compression_type = info.compression_type;
@@ -10798,7 +10921,7 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type,
256);
exr_header->custom_attributes[i].size = info.attributes[i].size;
- // Just copy poiner
+ // Just copy pointer
exr_header->custom_attributes[i].value = info.attributes[i].value;
}
@@ -10822,21 +10945,30 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
num_scanline_blocks = 32;
} else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
num_scanline_blocks = 16;
- }
- int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1;
- int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1;
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+ if (!FindZFPCompressionParam(&zfp_compression_param,
+ exr_header->custom_attributes,
+ int(exr_header->num_custom_attributes), err)) {
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+#endif
+ }
- if ((data_width < 0) || (data_height < 0)) {
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_y < exr_header->data_window.min_y) {
if (err) {
- std::stringstream ss;
- ss << "Invalid data width or data height: " << data_width << ", "
- << data_height << std::endl;
- (*err) += ss.str();
+ (*err) += "Invalid data window.\n";
}
return TINYEXR_ERROR_INVALID_DATA;
}
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
+
// Do not allow too large data_width and data_height. header invalid?
{
const int threshold = 1024 * 8192; // heuristics
@@ -10938,14 +11070,10 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
int tile_coordinates[4];
memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[0]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[1]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[2]));
- tinyexr::swap4(
- reinterpret_cast<unsigned int *>(&tile_coordinates[3]));
+ tinyexr::swap4(&tile_coordinates[0]);
+ tinyexr::swap4(&tile_coordinates[1]);
+ tinyexr::swap4(&tile_coordinates[2]);
+ tinyexr::swap4(&tile_coordinates[3]);
// @todo{ LoD }
if (tile_coordinates[2] != 0) {
@@ -10960,7 +11088,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
int data_len;
memcpy(&data_len, data_ptr + 16,
sizeof(int)); // 16 = sizeof(tile_coordinates)
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&data_len);
if (data_len < 4 || size_t(data_len) > data_size) {
// TODO(LTE): atomic
@@ -11081,8 +11209,8 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
memcpy(&line_no, data_ptr, sizeof(int));
int data_len;
memcpy(&data_len, data_ptr + 4, sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&line_no);
+ tinyexr::swap4(&data_len);
if (size_t(data_len) > data_size) {
invalid_data = true;
@@ -11098,7 +11226,7 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
} else {
// line_no may be negative.
int end_line_no = (std::min)(line_no + num_scanline_blocks,
- (exr_header->data_window[3] + 1));
+ (exr_header->data_window.max_y + 1));
int num_lines = end_line_no - line_no;
@@ -11113,13 +11241,13 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
// overflow check
tinyexr_int64 lno =
static_cast<tinyexr_int64>(line_no) -
- static_cast<tinyexr_int64>(exr_header->data_window[1]);
+ static_cast<tinyexr_int64>(exr_header->data_window.min_y);
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];
+ line_no -= exr_header->data_window.min_y;
}
if (line_no < 0) {
@@ -11204,8 +11332,8 @@ static bool ReconstructLineOffsets(
return false;
}
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&data_len);
(*offsets)[i] = offset;
@@ -11234,25 +11362,24 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
num_scanline_blocks = 16;
}
- int data_width = exr_header->data_window[2] - exr_header->data_window[0];
- if (data_width >= std::numeric_limits<int>::max()) {
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_x - exr_header->data_window.min_x ==
+ std::numeric_limits<int>::max()) {
// Issue 63
tinyexr::SetErrorMessage("Invalid data width value", err);
return TINYEXR_ERROR_INVALID_DATA;
}
- data_width++;
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
- int data_height = exr_header->data_window[3] - exr_header->data_window[1];
- if (data_height >= std::numeric_limits<int>::max()) {
+ if (exr_header->data_window.max_y < exr_header->data_window.min_y ||
+ exr_header->data_window.max_y - exr_header->data_window.min_y ==
+ std::numeric_limits<int>::max()) {
tinyexr::SetErrorMessage("Invalid data height value", err);
return TINYEXR_ERROR_INVALID_DATA;
}
- data_height++;
-
- if ((data_width < 0) || (data_height < 0)) {
- tinyexr::SetErrorMessage("data width or data height is negative.", err);
- return TINYEXR_ERROR_INVALID_DATA;
- }
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
// Do not allow too large data_width and data_height. header invalid?
{
@@ -11275,6 +11402,12 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
num_blocks = static_cast<size_t>(exr_header->chunk_count);
} else if (exr_header->tiled) {
// @todo { LoD }
+ if (exr_header->tile_size_x > data_width || exr_header->tile_size_x < 1 ||
+ exr_header->tile_size_y > data_height || exr_header->tile_size_y < 1) {
+ tinyexr::SetErrorMessage("tile sizes are invalid.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
size_t num_x_tiles = static_cast<size_t>(data_width) /
static_cast<size_t>(exr_header->tile_size_x);
if (num_x_tiles * static_cast<size_t>(exr_header->tile_size_x) <
@@ -11371,7 +11504,8 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
}
}
-static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& layer_names) {
+static void GetLayers(const EXRHeader &exr_header,
+ std::vector<std::string> &layer_names) {
// Naive implementation
// Group channels by layers
// go over all channel names, split by periods
@@ -11382,22 +11516,22 @@ static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& lay
const size_t pos = full_name.find_last_of('.');
if (pos != std::string::npos && pos != 0 && pos + 1 < full_name.size()) {
full_name.erase(pos);
- if (std::find(layer_names.begin(), layer_names.end(), full_name) == layer_names.end())
+ if (std::find(layer_names.begin(), layer_names.end(), full_name) ==
+ layer_names.end())
layer_names.push_back(full_name);
}
}
}
struct LayerChannel {
- explicit LayerChannel (size_t i, std::string n)
- : index(i)
- , name(n)
- {}
+ explicit LayerChannel(size_t i, std::string n) : index(i), name(n) {}
size_t index;
std::string name;
};
-static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer_name, std::vector<LayerChannel>& channels) {
+static void ChannelsInLayer(const EXRHeader &exr_header,
+ const std::string layer_name,
+ std::vector<LayerChannel> &channels) {
channels.clear();
for (int c = 0; c < exr_header.num_channels; c++) {
std::string ch_name(exr_header.channels[c].name);
@@ -11408,8 +11542,7 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer
}
} else {
const size_t pos = ch_name.find(layer_name + '.');
- if (pos == std::string::npos)
- continue;
+ if (pos == std::string::npos) continue;
if (pos == 0) {
ch_name = ch_name.substr(layer_name.size() + 1);
}
@@ -11421,7 +11554,8 @@ static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer
} // namespace tinyexr
-int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err) {
+int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
+ const char **err) {
EXRVersion exr_version;
EXRHeader exr_header;
InitEXRHeader(&exr_header);
@@ -11435,8 +11569,8 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
if (exr_version.multipart || exr_version.non_image) {
tinyexr::SetErrorMessage(
- "Loading multipart or DeepImage is not supported in LoadEXR() API",
- err);
+ "Loading multipart or DeepImage is not supported in LoadEXR() API",
+ err);
return TINYEXR_ERROR_INVALID_DATA; // @fixme.
}
}
@@ -11452,7 +11586,7 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
(*num_layers) = int(layer_vec.size());
(*layer_names) = static_cast<const char **>(
- malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
+ malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
for (size_t c = 0; c < static_cast<size_t>(layer_vec.size()); c++) {
#ifdef _MSC_VER
(*layer_names)[c] = _strdup(layer_vec[c].c_str());
@@ -11467,11 +11601,13 @@ int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
const char **err) {
- return LoadEXRWithLayer(out_rgba, width, height, filename, /* layername */NULL, err);
+ return LoadEXRWithLayer(out_rgba, width, height, filename,
+ /* layername */ NULL, err);
}
-int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *filename, const char *layername,
- const char **err) {
+int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
+ const char *filename, const char *layername,
+ const char **err) {
if (out_rgba == NULL) {
tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err);
return TINYEXR_ERROR_INVALID_ARGUMENT;
@@ -11487,7 +11623,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
int ret = ParseEXRVersionFromFile(&exr_version, filename);
if (ret != TINYEXR_SUCCESS) {
std::stringstream ss;
- ss << "Failed to open EXR file or read version info from EXR file. code(" << ret << ")";
+ ss << "Failed to open EXR file or read version info from EXR file. code("
+ << ret << ")";
tinyexr::SetErrorMessage(ss.str(), err);
return ret;
}
@@ -11534,7 +11671,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
tinyexr::GetLayers(exr_header, layer_names);
std::vector<tinyexr::LayerChannel> channels;
- tinyexr::ChannelsInLayer(exr_header, layername == NULL ? "" : std::string(layername), channels);
+ tinyexr::ChannelsInLayer(
+ exr_header, layername == NULL ? "" : std::string(layername), channels);
if (channels.size() < 1) {
tinyexr::SetErrorMessage("Layer Not Found", err);
@@ -11549,14 +11687,11 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
if (ch.name == "R") {
idxR = int(ch.index);
- }
- else if (ch.name == "G") {
+ } else if (ch.name == "G") {
idxG = int(ch.index);
- }
- else if (ch.name == "B") {
+ } else if (ch.name == "B") {
idxB = int(ch.index);
- }
- else if (ch.name == "A") {
+ } else if (ch.name == "A") {
idxA = int(ch.index);
}
}
@@ -11573,11 +11708,13 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
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++) {
- const int ii =
- exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
- const int jj =
- exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
- const int idx = ii + jj * exr_image.width;
+ const int ii = exr_image.tiles[it].offset_x *
+ static_cast<int>(exr_header.tile_size_x) +
+ i;
+ const int jj = exr_image.tiles[it].offset_y *
+ static_cast<int>(exr_header.tile_size_y) +
+ j;
+ const int idx = ii + jj * static_cast<int>(exr_image.width);
// out of region check.
if (ii >= exr_image.width) {
@@ -11601,7 +11738,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *file
}
} else {
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
- const float val = reinterpret_cast<float **>(exr_image.images)[chIdx][i];
+ const float val =
+ reinterpret_cast<float **>(exr_image.images)[chIdx][i];
(*out_rgba)[4 * i + 0] = val;
(*out_rgba)[4 * i + 1] = val;
(*out_rgba)[4 * i + 2] = val;
@@ -11947,11 +12085,22 @@ int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -12101,7 +12250,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
int comp = exr_header->compression_type;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&comp));
+ tinyexr::swap4(&comp);
tinyexr::WriteAttributeToMemory(
&memory, "compression", "compression",
reinterpret_cast<const unsigned char *>(&comp), 1);
@@ -12109,10 +12258,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
int data[4] = {0, 0, exr_image->width - 1, exr_image->height - 1};
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[1]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[2]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[3]));
+ tinyexr::swap4(&data[0]);
+ tinyexr::swap4(&data[1]);
+ tinyexr::swap4(&data[2]);
+ tinyexr::swap4(&data[3]);
tinyexr::WriteAttributeToMemory(
&memory, "dataWindow", "box2i",
reinterpret_cast<const unsigned char *>(data), sizeof(int) * 4);
@@ -12129,7 +12278,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float aspectRatio = 1.0f;
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&aspectRatio));
+ tinyexr::swap4(&aspectRatio);
tinyexr::WriteAttributeToMemory(
&memory, "pixelAspectRatio", "float",
reinterpret_cast<const unsigned char *>(&aspectRatio), sizeof(float));
@@ -12137,8 +12286,8 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float center[2] = {0.0f, 0.0f};
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[1]));
+ tinyexr::swap4(&center[0]);
+ tinyexr::swap4(&center[1]);
tinyexr::WriteAttributeToMemory(
&memory, "screenWindowCenter", "v2f",
reinterpret_cast<const unsigned char *>(center), 2 * sizeof(float));
@@ -12146,7 +12295,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
{
float w = static_cast<float>(exr_image->width);
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
+ tinyexr::swap4(&w);
tinyexr::WriteAttributeToMemory(&memory, "screenWindowWidth", "float",
reinterpret_cast<const unsigned char *>(&w),
sizeof(float));
@@ -12213,9 +12362,10 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
// Use ZFP compression parameter from custom attributes(if such a parameter
// exists)
{
+ std::string e;
bool ret = tinyexr::FindZFPCompressionParam(
&zfp_compression_param, exr_header->custom_attributes,
- exr_header->num_custom_attributes);
+ exr_header->num_custom_attributes, &e);
if (!ret) {
// Use predefined compression parameter.
@@ -12225,7 +12375,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
}
#endif
- // TOOD(LTE): C++11 thread
+ // TODO(LTE): C++11 thread
// Use signed int since some OpenMP compiler doesn't allow unsigned type for
// `parallel for`
@@ -12257,7 +12407,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
tinyexr::FP32 f32 = half_to_float(h16);
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&f32.f));
+ tinyexr::swap4(&f32.f);
// line_ptr[x] = f32.f;
tinyexr::cpy4(line_ptr + x, &(f32.f));
@@ -12321,7 +12471,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
float val = reinterpret_cast<float **>(
exr_image->images)[c][(y + start_y) * exr_image->width + x];
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+ tinyexr::swap4(&val);
// line_ptr[x] = val;
tinyexr::cpy4(line_ptr + x, &val);
@@ -12538,14 +12688,26 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
}
#endif
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "wb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"wb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+#else
+ // Unknown compiler
+ fp = fopen(filename, "wb");
+#endif
#else
- FILE *fp = fopen(filename, "wb");
+ fp = fopen(filename, "wb");
#endif
if (!fp) {
- tinyexr::SetErrorMessage("Cannot write a file", err);
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
return TINYEXR_ERROR_CANT_WRITE_FILE;
}
@@ -12577,10 +12739,21 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _MSC_VER
+#ifdef _WIN32
FILE *fp = NULL;
- errno_t errcode = fopen_s(&fp, filename, "rb");
- if ((0 != errcode) || (!fp)) {
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
err);
return TINYEXR_ERROR_CANT_OPEN_FILE;
@@ -12714,10 +12887,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&dy, &data.at(4), sizeof(int));
memcpy(&dw, &data.at(8), sizeof(int));
memcpy(&dh, &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dx));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dy));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dw));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&dh));
+ tinyexr::swap4(&dx);
+ tinyexr::swap4(&dy);
+ tinyexr::swap4(&dw);
+ tinyexr::swap4(&dh);
} else if (attr_name.compare("displayWindow") == 0) {
int x;
@@ -12728,10 +12901,10 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&y, &data.at(4), sizeof(int));
memcpy(&w, &data.at(8), sizeof(int));
memcpy(&h, &data.at(12), sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&x));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&h));
+ tinyexr::swap4(&x);
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&w);
+ tinyexr::swap4(&h);
}
}
@@ -12819,7 +12992,7 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
memcpy(&unpackedSampleDataSize, data_ptr + 20,
sizeof(tinyexr::tinyexr_int64));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
+ tinyexr::swap4(&line_no);
tinyexr::swap8(
reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedOffsetTableSize));
tinyexr::swap8(
@@ -13054,11 +13227,21 @@ int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13174,11 +13357,21 @@ int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13270,11 +13463,20 @@ int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) {
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t err = _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (err != 0) {
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
return TINYEXR_ERROR_CANT_OPEN_FILE;
@@ -13408,11 +13610,21 @@ int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
return TINYEXR_ERROR_INVALID_ARGUMENT;
}
-#ifdef _WIN32
FILE *fp = NULL;
- fopen_s(&fp, filename, "rb");
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
#else
- FILE *fp = fopen(filename, "rb");
+ // Unknown compiler
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
#endif
if (!fp) {
tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
@@ -13582,5 +13794,5 @@ int SaveEXR(const float *data, int width, int height, int components,
#pragma clang diagnostic pop
#endif
-#endif // TINYEXR_IMPLEMENTATION_DEIFNED
+#endif // TINYEXR_IMPLEMENTATION_DEFINED
#endif // TINYEXR_IMPLEMENTATION
diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h
index 1c294b80d1..37b99c01ee 100644
--- a/thirdparty/zstd/common/bitstream.h
+++ b/thirdparty/zstd/common/bitstream.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- bitstream
- Part of FSE library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * bitstream
+ * Part of FSE library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#ifndef BITSTREAM_H_MODULE
#define BITSTREAM_H_MODULE
@@ -48,6 +28,7 @@ extern "C" {
* Dependencies
******************************************/
#include "mem.h" /* unaligned access routines */
+#include "compiler.h" /* UNLIKELY() */
#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
#include "error_private.h" /* error codes and messages */
@@ -161,8 +142,7 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
{
# if defined(_MSC_VER) /* Visual */
unsigned long r=0;
- _BitScanReverse ( &r, val );
- return (unsigned) r;
+ return _BitScanReverse ( &r, val ) ? (unsigned)r : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
return __builtin_clz (val) ^ 31;
# elif defined(__ICCARM__) /* IAR Intrinsic */
@@ -411,6 +391,23 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
return value;
}
+/*! BIT_reloadDStreamFast() :
+ * Similar to BIT_reloadDStream(), but with two differences:
+ * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
+ * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this
+ * point you must use BIT_reloadDStream() to reload.
+ */
+MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
+{
+ if (UNLIKELY(bitD->ptr < bitD->limitPtr))
+ return BIT_DStream_overflow;
+ assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
+ bitD->ptr -= bitD->bitsConsumed >> 3;
+ bitD->bitsConsumed &= 7;
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
+ return BIT_DStream_unfinished;
+}
+
/*! BIT_reloadDStream() :
* Refill `bitD` from buffer previously set in BIT_initDStream() .
* This function is safe, it guarantees it will not read beyond src buffer.
@@ -422,10 +419,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
return BIT_DStream_overflow;
if (bitD->ptr >= bitD->limitPtr) {
- bitD->ptr -= bitD->bitsConsumed >> 3;
- bitD->bitsConsumed &= 7;
- bitD->bitContainer = MEM_readLEST(bitD->ptr);
- return BIT_DStream_unfinished;
+ return BIT_reloadDStreamFast(bitD);
}
if (bitD->ptr == bitD->start) {
if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h
index 1877a0c1d9..95e9483521 100644
--- a/thirdparty/zstd/common/compiler.h
+++ b/thirdparty/zstd/common/compiler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -17,7 +17,7 @@
/* force inlining */
#if !defined(ZSTD_NO_INLINE)
-#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# define INLINE_KEYWORD inline
#else
# define INLINE_KEYWORD
@@ -114,6 +114,9 @@
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
+# elif defined(__aarch64__)
+# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
+# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
@@ -136,7 +139,7 @@
/* vectorization
* older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
-#if !defined(__clang__) && defined(__GNUC__)
+#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__)
# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
# else
@@ -146,6 +149,19 @@
# define DONT_VECTORIZE
#endif
+/* Tell the compiler that a branch is likely or unlikely.
+ * Only use these macros if it causes the compiler to generate better code.
+ * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc
+ * and clang, please do.
+ */
+#if defined(__GNUC__)
+#define LIKELY(x) (__builtin_expect((x), 1))
+#define UNLIKELY(x) (__builtin_expect((x), 0))
+#else
+#define LIKELY(x) (x)
+#define UNLIKELY(x) (x)
+#endif
+
/* disable warnings */
#ifdef _MSC_VER /* Visual Studio */
# include <intrin.h> /* For Visual 2005 */
diff --git a/thirdparty/zstd/common/cpu.h b/thirdparty/zstd/common/cpu.h
index 5f0923fc92..6e8a974f62 100644
--- a/thirdparty/zstd/common/cpu.h
+++ b/thirdparty/zstd/common/cpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-present, Facebook, Inc.
+ * Copyright (c) 2018-2020, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/common/debug.c b/thirdparty/zstd/common/debug.c
index 3ebdd1cb15..f303f4a2e5 100644
--- a/thirdparty/zstd/common/debug.c
+++ b/thirdparty/zstd/common/debug.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- debug
- Part of FSE library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * debug
+ * Part of FSE library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
diff --git a/thirdparty/zstd/common/debug.h b/thirdparty/zstd/common/debug.h
index b4fc89d497..ac6224888d 100644
--- a/thirdparty/zstd/common/debug.h
+++ b/thirdparty/zstd/common/debug.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- debug
- Part of FSE library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * debug
+ * Part of FSE library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
diff --git a/thirdparty/zstd/common/entropy_common.c b/thirdparty/zstd/common/entropy_common.c
index b12944e1de..9d3e4e8e36 100644
--- a/thirdparty/zstd/common/entropy_common.c
+++ b/thirdparty/zstd/common/entropy_common.c
@@ -1,36 +1,16 @@
-/*
- Common functions of New Generation Entropy library
- Copyright (C) 2016, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
-*************************************************************************** */
+/* ******************************************************************
+ * Common functions of New Generation Entropy library
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+****************************************************************** */
/* *************************************
* Dependencies
diff --git a/thirdparty/zstd/common/error_private.c b/thirdparty/zstd/common/error_private.c
index 7c1bb67a23..cd437529c1 100644
--- a/thirdparty/zstd/common/error_private.c
+++ b/thirdparty/zstd/common/error_private.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -47,6 +47,7 @@ const char* ERR_getErrorString(ERR_enum code)
/* following error codes are not stable and may be removed or changed in a future version */
case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
+ case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
case PREFIX(maxCode):
default: return notErrorCode;
}
diff --git a/thirdparty/zstd/common/error_private.h b/thirdparty/zstd/common/error_private.h
index 0d2fa7e34b..982cf8e9fe 100644
--- a/thirdparty/zstd/common/error_private.h
+++ b/thirdparty/zstd/common/error_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -49,7 +49,7 @@ typedef ZSTD_ErrorCode ERR_enum;
/*-****************************************
* Error codes handling
******************************************/
-#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
+#undef ERROR /* already defined on Visual Studio */
#define ERROR(name) ZSTD_ERROR(name)
#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
@@ -57,6 +57,10 @@ ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
+/* check and forward error code */
+#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
+#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
+
/*-****************************************
* Error Strings
diff --git a/thirdparty/zstd/common/fse.h b/thirdparty/zstd/common/fse.h
index a7553e3721..ff54e70ea7 100644
--- a/thirdparty/zstd/common/fse.h
+++ b/thirdparty/zstd/common/fse.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy codec
- Public Prototypes declaration
- Copyright (C) 2013-2016, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * FSE : Finite State Entropy codec
+ * Public Prototypes declaration
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#if defined (__cplusplus)
diff --git a/thirdparty/zstd/common/fse_decompress.c b/thirdparty/zstd/common/fse_decompress.c
index 4f07378982..bcc2223ccc 100644
--- a/thirdparty/zstd/common/fse_decompress.c
+++ b/thirdparty/zstd/common/fse_decompress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy decoder
- Copyright (C) 2013-2015, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ * FSE : Finite State Entropy decoder
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
@@ -51,11 +31,6 @@
#define FSE_isError ERR_isError
#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
-/* check and forward error code */
-#ifndef CHECK_F
-#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
-#endif
-
/* **************************************************************
* Templates
@@ -287,7 +262,7 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size
/* normal FSE decoding mode */
size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
if (FSE_isError(NCountLength)) return NCountLength;
- //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
+ /* if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); */ /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
ip += NCountLength;
cSrcSize -= NCountLength;
diff --git a/thirdparty/zstd/common/huf.h b/thirdparty/zstd/common/huf.h
index 6b572c448d..ef432685da 100644
--- a/thirdparty/zstd/common/huf.h
+++ b/thirdparty/zstd/common/huf.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- huff0 huffman codec,
- part of Finite State Entropy library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * huff0 huffman codec,
+ * part of Finite State Entropy library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#if defined (__cplusplus)
@@ -110,7 +90,7 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
/** HUF_compress4X_wksp() :
* Same as HUF_compress2(), but uses externally allocated `workSpace`.
* `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */
-#define HUF_WORKSPACE_SIZE (6 << 10)
+#define HUF_WORKSPACE_SIZE ((6 << 10) + 256)
#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -208,6 +188,8 @@ typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
+size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
+int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
typedef enum {
HUF_repeat_none, /**< Cannot use the previous table */
@@ -246,7 +228,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
/** HUF_readCTable() :
* Loading a CTable saved with HUF_writeCTable() */
-size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
+size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
/** HUF_getNbBits() :
* Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h
index 530d30c8f7..89c8aea7d2 100644
--- a/thirdparty/zstd/common/mem.h
+++ b/thirdparty/zstd/common/mem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/common/pool.c b/thirdparty/zstd/common/pool.c
index f575935076..aa4b4de0d3 100644
--- a/thirdparty/zstd/common/pool.c
+++ b/thirdparty/zstd/common/pool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/common/pool.h b/thirdparty/zstd/common/pool.h
index 458d37f13c..259bafc975 100644
--- a/thirdparty/zstd/common/pool.h
+++ b/thirdparty/zstd/common/pool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -18,7 +18,7 @@ extern "C" {
#include <stddef.h> /* size_t */
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
-#include "zstd.h"
+#include "../zstd.h"
typedef struct POOL_ctx_s POOL_ctx;
diff --git a/thirdparty/zstd/common/threading.c b/thirdparty/zstd/common/threading.c
index 482664bd9a..e2edb313eb 100644
--- a/thirdparty/zstd/common/threading.c
+++ b/thirdparty/zstd/common/threading.c
@@ -2,12 +2,13 @@
* Copyright (c) 2016 Tino Reichardt
* All rights reserved.
*
+ * You can contact the author at:
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ *
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
- *
- * You can contact the author at:
- * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ * You may select, at your option, one of the above-listed licenses.
*/
/**
diff --git a/thirdparty/zstd/common/threading.h b/thirdparty/zstd/common/threading.h
index 3193ca7db8..fd0060d5aa 100644
--- a/thirdparty/zstd/common/threading.h
+++ b/thirdparty/zstd/common/threading.h
@@ -2,12 +2,13 @@
* Copyright (c) 2016 Tino Reichardt
* All rights reserved.
*
+ * You can contact the author at:
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ *
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
- *
- * You can contact the author at:
- * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ * You may select, at your option, one of the above-listed licenses.
*/
#ifndef THREADING_H_938743
diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c
index 99d2459621..597de18fc8 100644
--- a/thirdparty/zstd/common/xxhash.c
+++ b/thirdparty/zstd/common/xxhash.c
@@ -1,35 +1,15 @@
/*
-* xxHash - Fast Hash algorithm
-* Copyright (C) 2012-2016, Yann Collet
-*
-* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are
-* met:
-*
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following disclaimer
-* in the documentation and/or other materials provided with the
-* distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* You can contact the author at :
-* - xxHash homepage: http://www.xxhash.com
-* - xxHash source repository : https://github.com/Cyan4973/xxHash
+ * xxHash - Fast Hash algorithm
+ * Copyright (c) 2012-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - xxHash homepage: http://www.xxhash.com
+ * - xxHash source repository : https://github.com/Cyan4973/xxHash
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
*/
@@ -115,7 +95,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
/* *************************************
* Compiler Specific Options
***************************************/
-#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# define INLINE_KEYWORD inline
#else
# define INLINE_KEYWORD
@@ -729,7 +709,9 @@ FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, c
state->total_len += len;
if (state->memsize + len < 32) { /* fill in tmp buffer */
- XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+ if (input != NULL) {
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+ }
state->memsize += (U32)len;
return XXH_OK;
}
diff --git a/thirdparty/zstd/common/xxhash.h b/thirdparty/zstd/common/xxhash.h
index 9bad1f59f6..4207eba832 100644
--- a/thirdparty/zstd/common/xxhash.h
+++ b/thirdparty/zstd/common/xxhash.h
@@ -1,35 +1,15 @@
/*
- xxHash - Extremely Fast Hash algorithm
- Header File
- Copyright (C) 2012-2016, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - xxHash source repository : https://github.com/Cyan4973/xxHash
+ * xxHash - Extremely Fast Hash algorithm
+ * Header File
+ * Copyright (c) 2012-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - xxHash source repository : https://github.com/Cyan4973/xxHash
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
*/
/* Notice extracted from xxHash homepage :
diff --git a/thirdparty/zstd/common/zstd_common.c b/thirdparty/zstd/common/zstd_common.c
index 667f4a27fc..91fe3323a5 100644
--- a/thirdparty/zstd/common/zstd_common.c
+++ b/thirdparty/zstd/common/zstd_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/common/zstd_errors.h b/thirdparty/zstd/common/zstd_errors.h
index 92a3433896..998398e7e5 100644
--- a/thirdparty/zstd/common/zstd_errors.h
+++ b/thirdparty/zstd/common/zstd_errors.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -76,6 +76,7 @@ typedef enum {
/* following error codes are __NOT STABLE__, they can be removed or changed in future versions */
ZSTD_error_frameIndex_tooLarge = 100,
ZSTD_error_seekableIO = 102,
+ ZSTD_error_dstBuffer_wrong = 104,
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
} ZSTD_ErrorCode;
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
index dcdcbdb81c..3bc7e55a0a 100644
--- a/thirdparty/zstd/common/zstd_internal.h
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -19,12 +19,15 @@
/*-*************************************
* Dependencies
***************************************/
+#ifdef __aarch64__
+#include <arm_neon.h>
+#endif
#include "compiler.h"
#include "mem.h"
#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
#include "error_private.h"
#define ZSTD_STATIC_LINKING_ONLY
-#include "zstd.h"
+#include "../zstd.h"
#define FSE_STATIC_LINKING_ONLY
#include "fse.h"
#define HUF_STATIC_LINKING_ONLY
@@ -54,6 +57,31 @@ extern "C" {
#define MAX(a,b) ((a)>(b) ? (a) : (b))
/**
+ * Ignore: this is an internal helper.
+ *
+ * This is a helper function to help force C99-correctness during compilation.
+ * Under strict compilation modes, variadic macro arguments can't be empty.
+ * However, variadic function arguments can be. Using a function therefore lets
+ * us statically check that at least one (string) argument was passed,
+ * independent of the compilation flags.
+ */
+static INLINE_KEYWORD UNUSED_ATTR
+void _force_has_format_string(const char *format, ...) {
+ (void)format;
+}
+
+/**
+ * Ignore: this is an internal helper.
+ *
+ * We want to force this function invocation to be syntactically correct, but
+ * we don't want to force runtime evaluation of its arguments.
+ */
+#define _FORCE_HAS_FORMAT_STRING(...) \
+ if (0) { \
+ _force_has_format_string(__VA_ARGS__); \
+ }
+
+/**
* Return the specified error if the condition evaluates to true.
*
* In debug modes, prints additional information.
@@ -62,7 +90,9 @@ extern "C" {
*/
#define RETURN_ERROR_IF(cond, err, ...) \
if (cond) { \
- RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
+ RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
+ __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
RAWLOG(3, ": " __VA_ARGS__); \
RAWLOG(3, "\n"); \
return ERROR(err); \
@@ -75,7 +105,9 @@ extern "C" {
*/
#define RETURN_ERROR(err, ...) \
do { \
- RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
+ RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
+ __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
RAWLOG(3, ": " __VA_ARGS__); \
RAWLOG(3, "\n"); \
return ERROR(err); \
@@ -90,7 +122,9 @@ extern "C" {
do { \
size_t const err_code = (err); \
if (ERR_isError(err_code)) { \
- RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
+ RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
+ __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
RAWLOG(3, ": " __VA_ARGS__); \
RAWLOG(3, "\n"); \
return err_code; \
@@ -128,6 +162,8 @@ static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
+#define ZSTD_FRAMECHECKSUMSIZE 4
+
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
@@ -191,10 +227,22 @@ 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); }
+static void ZSTD_copy8(void* dst, const void* src) {
+#ifdef __aarch64__
+ vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
+#else
+ memcpy(dst, src, 8);
+#endif
+}
#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
-static void ZSTD_copy16(void* dst, const void* src) { memcpy(dst, src, 16); }
+static void ZSTD_copy16(void* dst, const void* src) {
+#ifdef __aarch64__
+ vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
+#else
+ memcpy(dst, src, 16);
+#endif
+}
#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
#define WILDCOPY_OVERLENGTH 32
@@ -213,7 +261,7 @@ typedef enum {
* - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
* The src buffer must be before the dst buffer.
*/
-MEM_STATIC FORCE_INLINE_ATTR DONT_VECTORIZE
+MEM_STATIC FORCE_INLINE_ATTR
void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
{
ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
@@ -230,13 +278,18 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e
} while (op < oend);
} else {
assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
- /* Separate out the first two COPY16() calls because the copy length is
+ /* Separate out the first COPY16() call because the copy length is
* almost certain to be short, so the branches have different
- * probabilities.
- * On gcc-9 unrolling once is +1.6%, twice is +2%, thrice is +1.8%.
- * On clang-8 unrolling once is +1.4%, twice is +3.3%, thrice is +3%.
+ * probabilities. Since it is almost certain to be short, only do
+ * one COPY16() in the first call. Then, do two calls per loop since
+ * at that point it is more likely to have a high trip count.
*/
- COPY16(op, ip);
+#ifndef __aarch64__
+ do {
+ COPY16(op, ip);
+ }
+ while (op < oend);
+#else
COPY16(op, ip);
if (op >= oend) return;
do {
@@ -244,9 +297,29 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e
COPY16(op, ip);
}
while (op < oend);
+#endif
+ }
+}
+
+MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ size_t const length = MIN(dstCapacity, srcSize);
+ if (length > 0) {
+ memcpy(dst, src, length);
}
+ return length;
}
+/* define "workspace is too large" as this number of times larger than needed */
+#define ZSTD_WORKSPACETOOLARGE_FACTOR 3
+
+/* when workspace is continuously too large
+ * during at least this number of times,
+ * context's memory usage is considered wasteful,
+ * because it's sized to handle a worst case scenario which rarely happens.
+ * In which case, resize it down to free some memory */
+#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
+
/*-*******************************************
* Private declarations
@@ -271,6 +344,31 @@ typedef struct {
U32 longLengthPos;
} seqStore_t;
+typedef struct {
+ U32 litLength;
+ U32 matchLength;
+} ZSTD_sequenceLength;
+
+/**
+ * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
+ * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
+ */
+MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
+{
+ ZSTD_sequenceLength seqLen;
+ seqLen.litLength = seq->litLength;
+ seqLen.matchLength = seq->matchLength + MINMATCH;
+ if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
+ if (seqStore->longLengthID == 1) {
+ seqLen.litLength += 0xFFFF;
+ }
+ if (seqStore->longLengthID == 2) {
+ seqLen.matchLength += 0xFFFF;
+ }
+ }
+ return seqLen;
+}
+
/**
* Contains the compressed frame size and an upper-bound for the decompressed frame size.
* Note: before using `compressedSize`, check for errors using ZSTD_isError().
@@ -297,8 +395,7 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus
{
# if defined(_MSC_VER) /* Visual */
unsigned long r=0;
- _BitScanReverse(&r, val);
- return (unsigned)r;
+ return _BitScanReverse(&r, val) ? (unsigned)r : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return __builtin_clz (val) ^ 31;
# elif defined(__ICCARM__) /* IAR Intrinsic */
diff --git a/thirdparty/zstd/compress/fse_compress.c b/thirdparty/zstd/compress/fse_compress.c
index 68b47e1093..a42759814f 100644
--- a/thirdparty/zstd/compress/fse_compress.c
+++ b/thirdparty/zstd/compress/fse_compress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy encoder
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ * FSE : Finite State Entropy encoder
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* **************************************************************
@@ -37,14 +17,14 @@
****************************************************************/
#include <stdlib.h> /* malloc, free, qsort */
#include <string.h> /* memcpy, memset */
-#include "compiler.h"
-#include "mem.h" /* U32, U16, etc. */
-#include "debug.h" /* assert, DEBUGLOG */
+#include "../common/compiler.h"
+#include "../common/mem.h" /* U32, U16, etc. */
+#include "../common/debug.h" /* assert, DEBUGLOG */
#include "hist.h" /* HIST_count_wksp */
-#include "bitstream.h"
+#include "../common/bitstream.h"
#define FSE_STATIC_LINKING_ONLY
-#include "fse.h"
-#include "error_private.h"
+#include "../common/fse.h"
+#include "../common/error_private.h"
/* **************************************************************
@@ -645,9 +625,6 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
-#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
-#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
-
/* FSE_compress_wksp() :
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
* `wkspSize` size must be `(1<<tableLog)`.
diff --git a/thirdparty/zstd/compress/hist.c b/thirdparty/zstd/compress/hist.c
index 45b7babc1e..61e08c7968 100644
--- a/thirdparty/zstd/compress/hist.c
+++ b/thirdparty/zstd/compress/hist.c
@@ -1,42 +1,22 @@
/* ******************************************************************
- hist : Histogram functions
- part of Finite State Entropy project
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ * hist : Histogram functions
+ * part of Finite State Entropy project
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* --- dependencies --- */
-#include "mem.h" /* U32, BYTE, etc. */
-#include "debug.h" /* assert, DEBUGLOG */
-#include "error_private.h" /* ERROR */
+#include "../common/mem.h" /* U32, BYTE, etc. */
+#include "../common/debug.h" /* assert, DEBUGLOG */
+#include "../common/error_private.h" /* ERROR */
#include "hist.h"
diff --git a/thirdparty/zstd/compress/hist.h b/thirdparty/zstd/compress/hist.h
index 8b389358dc..77e3ec4fb1 100644
--- a/thirdparty/zstd/compress/hist.h
+++ b/thirdparty/zstd/compress/hist.h
@@ -1,36 +1,16 @@
/* ******************************************************************
- hist : Histogram functions
- part of Finite State Entropy project
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ * hist : Histogram functions
+ * part of Finite State Entropy project
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* --- dependencies --- */
diff --git a/thirdparty/zstd/compress/huf_compress.c b/thirdparty/zstd/compress/huf_compress.c
index f074f1e0a9..546879868a 100644
--- a/thirdparty/zstd/compress/huf_compress.c
+++ b/thirdparty/zstd/compress/huf_compress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- Huffman encoder, part of New Generation Entropy library
- Copyright (C) 2013-2016, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ * Huffman encoder, part of New Generation Entropy library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* **************************************************************
@@ -45,14 +25,14 @@
****************************************************************/
#include <string.h> /* memcpy, memset */
#include <stdio.h> /* printf (debug) */
-#include "compiler.h"
-#include "bitstream.h"
+#include "../common/compiler.h"
+#include "../common/bitstream.h"
#include "hist.h"
#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
-#include "fse.h" /* header compression */
+#include "../common/fse.h" /* header compression */
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
-#include "error_private.h"
+#include "../common/huf.h"
+#include "../common/error_private.h"
/* **************************************************************
@@ -60,8 +40,6 @@
****************************************************************/
#define HUF_isError ERR_isError
#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
-#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
-#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
/* **************************************************************
@@ -110,18 +88,18 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
/* Write table description header */
- { CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
+ { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
op += hSize;
}
/* Compress */
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
- { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
+ { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, CTable) );
if (cSize == 0) return 0; /* not enough space for compressed data */
op += cSize;
}
- return op-ostart;
+ return (size_t)(op-ostart);
}
@@ -169,7 +147,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
}
-size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize)
+size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights)
{
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
@@ -192,9 +170,11 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
} }
/* fill nbBits */
+ *hasZeroWeights = 0;
{ U32 n; for (n=0; n<nbSymbols; n++) {
const U32 w = huffWeight[n];
- CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
+ *hasZeroWeights |= (w == 0);
+ CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0);
} }
/* fill val */
@@ -240,7 +220,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
/* there are several too large elements (at least >= 2) */
{ int totalCost = 0;
const U32 baseCost = 1 << (largestBits - maxNbBits);
- U32 n = lastNonNull;
+ int n = (int)lastNonNull;
while (huffNode[n].nbBits > maxNbBits) {
totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
@@ -255,22 +235,22 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
/* repay normalized cost */
{ U32 const noSymbol = 0xF0F0F0F0;
U32 rankLast[HUF_TABLELOG_MAX+2];
- int pos;
/* Get pos of last (smallest) symbol per rank */
memset(rankLast, 0xF0, sizeof(rankLast));
{ U32 currentNbBits = maxNbBits;
+ int pos;
for (pos=n ; pos >= 0; pos--) {
if (huffNode[pos].nbBits >= currentNbBits) continue;
currentNbBits = huffNode[pos].nbBits; /* < maxNbBits */
- rankLast[maxNbBits-currentNbBits] = pos;
+ rankLast[maxNbBits-currentNbBits] = (U32)pos;
} }
while (totalCost > 0) {
- U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
+ U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
- U32 highPos = rankLast[nBitsToDecrease];
- U32 lowPos = rankLast[nBitsToDecrease-1];
+ U32 const highPos = rankLast[nBitsToDecrease];
+ U32 const lowPos = rankLast[nBitsToDecrease-1];
if (highPos == noSymbol) continue;
if (lowPos == noSymbol) break;
{ U32 const highTotal = huffNode[highPos].count;
@@ -297,7 +277,8 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
while (huffNode[n].nbBits == maxNbBits) n--;
huffNode[n+1].nbBits--;
- rankLast[1] = n+1;
+ assert(n >= 0);
+ rankLast[1] = (U32)(n+1);
totalCost++;
continue;
}
@@ -309,29 +290,36 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
return maxNbBits;
}
-
typedef struct {
U32 base;
U32 current;
} rankPos;
-static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue)
+typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
+
+#define RANK_POSITION_TABLE_SIZE 32
+
+typedef struct {
+ huffNodeTable huffNodeTbl;
+ rankPos rankPosition[RANK_POSITION_TABLE_SIZE];
+} HUF_buildCTable_wksp_tables;
+
+static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition)
{
- rankPos rank[32];
U32 n;
- memset(rank, 0, sizeof(rank));
+ memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
for (n=0; n<=maxSymbolValue; n++) {
U32 r = BIT_highbit32(count[n] + 1);
- rank[r].base ++;
+ rankPosition[r].base ++;
}
- for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
- for (n=0; n<32; n++) rank[n].current = rank[n].base;
+ for (n=30; n>0; n--) rankPosition[n-1].base += rankPosition[n].base;
+ for (n=0; n<32; n++) rankPosition[n].current = rankPosition[n].base;
for (n=0; n<=maxSymbolValue; n++) {
U32 const c = count[n];
U32 const r = BIT_highbit32(c+1) + 1;
- U32 pos = rank[r].current++;
- while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) {
+ U32 pos = rankPosition[r].current++;
+ while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) {
huffNode[pos] = huffNode[pos-1];
pos--;
}
@@ -343,45 +331,48 @@ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValu
/** HUF_buildCTable_wksp() :
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
- * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of HUF_CTABLE_WORKSPACE_SIZE_U32 unsigned.
+ * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as sizeof(HUF_buildCTable_wksp_tables).
*/
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
-typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
+
size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
{
- nodeElt* const huffNode0 = (nodeElt*)workSpace;
+ HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
+ nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
nodeElt* const huffNode = huffNode0+1;
- U32 n, nonNullRank;
+ int nonNullRank;
int lowS, lowN;
- U16 nodeNb = STARTNODE;
- U32 nodeRoot;
+ int nodeNb = STARTNODE;
+ int n, nodeRoot;
/* safety checks */
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
- if (wkspSize < sizeof(huffNodeTable)) return ERROR(workSpace_tooSmall);
+ if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
+ return ERROR(workSpace_tooSmall);
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
- if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
+ return ERROR(maxSymbolValue_tooLarge);
memset(huffNode0, 0, sizeof(huffNodeTable));
/* sort, decreasing order */
- HUF_sort(huffNode, count, maxSymbolValue);
+ HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
/* init for parents */
- nonNullRank = maxSymbolValue;
+ nonNullRank = (int)maxSymbolValue;
while(huffNode[nonNullRank].count == 0) nonNullRank--;
lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
- huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
+ huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb;
nodeNb++; lowS-=2;
for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */
/* create parents */
while (nodeNb <= nodeRoot) {
- U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
- U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
+ int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
+ int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
- huffNode[n1].parent = huffNode[n2].parent = nodeNb;
+ huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb;
nodeNb++;
}
@@ -393,24 +384,25 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo
huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
/* enforce maxTableLog */
- maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
+ maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
/* fill result into tree (val, nbBits) */
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
+ int const alphabetSize = (int)(maxSymbolValue + 1);
if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
for (n=0; n<=nonNullRank; n++)
nbPerRank[huffNode[n].nbBits]++;
/* determine stating value per rank */
{ U16 min = 0;
- for (n=maxNbBits; n>0; n--) {
+ for (n=(int)maxNbBits; n>0; n--) {
valPerRank[n] = min; /* get starting value within each rank */
min += nbPerRank[n];
min >>= 1;
} }
- for (n=0; n<=maxSymbolValue; n++)
+ for (n=0; n<alphabetSize; n++)
tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
- for (n=0; n<=maxSymbolValue; n++)
+ for (n=0; n<alphabetSize; n++)
tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
}
@@ -423,11 +415,11 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo
*/
size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
{
- huffNodeTable nodeTable;
- return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable));
+ HUF_buildCTable_wksp_tables workspace;
+ return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
}
-static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
+size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
{
size_t nbBits = 0;
int s;
@@ -437,7 +429,7 @@ static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count
return nbBits >> 3;
}
-static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
+int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
int bad = 0;
int s;
for (s = 0; s <= (int)maxSymbolValue; ++s) {
@@ -476,7 +468,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
/* init */
if (dstSize < 8) return 0; /* not enough space to compress */
- { size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
+ { size_t const initErr = BIT_initCStream(&bitC, op, (size_t)(oend-op));
if (HUF_isError(initErr)) return 0; }
n = srcSize & ~3; /* join to mod 4 */
@@ -573,7 +565,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
if (srcSize < 12) return 0; /* no saving possible : too small input */
op += 6; /* jumpTable */
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart, (U16)cSize);
@@ -581,7 +574,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart+2, (U16)cSize);
@@ -589,7 +583,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart+4, (U16)cSize);
@@ -597,12 +592,14 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, iend-ip, CTable, bmi2) );
+ assert(op <= oend);
+ assert(ip <= iend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, bmi2) );
if (cSize==0) return 0;
op += cSize;
}
- return op-ostart;
+ return (size_t)(op-ostart);
}
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
@@ -618,20 +615,21 @@ static size_t HUF_compressCTable_internal(
HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)
{
size_t const cSize = (nbStreams==HUF_singleStream) ?
- HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2) :
- HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2);
+ HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, bmi2) :
+ HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, bmi2);
if (HUF_isError(cSize)) { return cSize; }
if (cSize==0) { return 0; } /* uncompressible */
op += cSize;
/* check compressibility */
+ assert(op >= ostart);
if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
- return op-ostart;
+ return (size_t)(op-ostart);
}
typedef struct {
unsigned count[HUF_SYMBOLVALUE_MAX + 1];
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];
- huffNodeTable nodeTable;
+ HUF_buildCTable_wksp_tables buildCTable_wksp;
} HUF_compress_tables_t;
/* HUF_compress_internal() :
@@ -650,6 +648,8 @@ HUF_compress_internal (void* dst, size_t dstSize,
BYTE* const oend = ostart + dstSize;
BYTE* op = ostart;
+ HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
+
/* checks & inits */
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
@@ -691,7 +691,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
{ size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
maxSymbolValue, huffLog,
- table->nodeTable, sizeof(table->nodeTable));
+ &table->buildCTable_wksp, sizeof(table->buildCTable_wksp));
CHECK_F(maxBits);
huffLog = (U32)maxBits;
/* Zero unused symbols in CTable, so we can check it for validity */
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
index 35346b92cb..3f963b1cff 100644
--- a/thirdparty/zstd/compress/zstd_compress.c
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -13,13 +13,13 @@
***************************************/
#include <limits.h> /* INT_MAX */
#include <string.h> /* memset */
-#include "cpu.h"
-#include "mem.h"
+#include "../common/cpu.h"
+#include "../common/mem.h"
#include "hist.h" /* HIST_countFast_wksp */
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
-#include "fse.h"
+#include "../common/fse.h"
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
+#include "../common/huf.h"
#include "zstd_compress_internal.h"
#include "zstd_compress_sequences.h"
#include "zstd_compress_literals.h"
@@ -28,11 +28,19 @@
#include "zstd_lazy.h"
#include "zstd_opt.h"
#include "zstd_ldm.h"
+#include "zstd_compress_superblock.h"
/*-*************************************
* Helper functions
***************************************/
+/* ZSTD_compressBound()
+ * Note that the result from this function is only compatible with the "normal"
+ * full-block strategy.
+ * When there are a lot of small blocks due to frequent flush in streaming mode
+ * the overhead of headers can make the compressed data to be larger than the
+ * return value of ZSTD_compressBound().
+ */
size_t ZSTD_compressBound(size_t srcSize) {
return ZSTD_COMPRESSBOUND(srcSize);
}
@@ -82,7 +90,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
}
}
-ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
+ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
{
ZSTD_cwksp ws;
ZSTD_CCtx* cctx;
@@ -91,9 +99,8 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
- if (cctx == NULL) {
- return NULL;
- }
+ if (cctx == NULL) return NULL;
+
memset(cctx, 0, sizeof(ZSTD_CCtx));
ZSTD_cwksp_move(&cctx->workspace, &ws);
cctx->staticSize = workspaceSize;
@@ -102,8 +109,7 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
- cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(
- &cctx->workspace, HUF_WORKSPACE_SIZE);
+ cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, HUF_WORKSPACE_SIZE);
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
return cctx;
}
@@ -227,7 +233,7 @@ size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
}
size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
- RETURN_ERROR_IF(!cctxParams, GENERIC);
+ RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
memset(cctxParams, 0, sizeof(*cctxParams));
cctxParams->compressionLevel = compressionLevel;
cctxParams->fParams.contentSizeFlag = 1;
@@ -236,8 +242,8 @@ size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel)
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
{
- RETURN_ERROR_IF(!cctxParams, GENERIC);
- FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
+ RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
memset(cctxParams, 0, sizeof(*cctxParams));
assert(!ZSTD_checkCParams(params.cParams));
cctxParams->cParams = params.cParams;
@@ -249,12 +255,12 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
/* ZSTD_assignParamsToCCtxParams() :
* params is presumed valid at this stage */
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
- const ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
+ const ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
{
ZSTD_CCtx_params ret = *cctxParams;
- assert(!ZSTD_checkCParams(params.cParams));
- ret.cParams = params.cParams;
- ret.fParams = params.fParams;
+ assert(!ZSTD_checkCParams(params->cParams));
+ ret.cParams = params->cParams;
+ ret.fParams = params->fParams;
ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
return ret;
}
@@ -339,8 +345,13 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
return bounds;
case ZSTD_c_overlapLog:
+#ifdef ZSTD_MULTITHREAD
bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;
bounds.upperBound = ZSTD_OVERLAPLOG_MAX;
+#else
+ bounds.lowerBound = 0;
+ bounds.upperBound = 0;
+#endif
return bounds;
case ZSTD_c_enableLongDistanceMatching:
@@ -408,9 +419,8 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
return bounds;
default:
- { ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
- return boundError;
- }
+ bounds.error = ERROR(parameter_unsupported);
+ return bounds;
}
}
@@ -428,7 +438,7 @@ static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
#define BOUNDCHECK(cParam, val) { \
RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
- parameter_outOfBound); \
+ parameter_outOfBound, "Param out of bounds"); \
}
@@ -476,7 +486,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
if (ZSTD_isUpdateAuthorized(param)) {
cctx->cParamsChanged = 1;
} else {
- RETURN_ERROR(stage_wrong);
+ RETURN_ERROR(stage_wrong, "can only set params in ctx init stage");
} }
switch(param)
@@ -513,7 +523,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_srcSizeHint:
break;
- default: RETURN_ERROR(parameter_unsupported);
+ default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
}
return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);
}
@@ -530,7 +540,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
return (size_t)CCtxParams->format;
case ZSTD_c_compressionLevel : {
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
if (value) { /* 0 : does not change current level */
CCtxParams->compressionLevel = value;
}
@@ -618,7 +628,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
return 0;
#else
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
CCtxParams->nbWorkers = value;
return CCtxParams->nbWorkers;
#endif
@@ -631,7 +641,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
/* Adjust to the minimum non-default value. */
if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)
value = ZSTDMT_JOBSIZE_MIN;
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
assert(value >= 0);
CCtxParams->jobSize = value;
return CCtxParams->jobSize;
@@ -642,7 +652,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
return 0;
#else
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
CCtxParams->overlapLog = value;
return CCtxParams->overlapLog;
#endif
@@ -652,7 +662,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
return 0;
#else
- FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));
+ FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), "");
CCtxParams->rsyncable = value;
return CCtxParams->rsyncable;
#endif
@@ -681,7 +691,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
case ZSTD_c_ldmHashRateLog :
RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,
- parameter_outOfBound);
+ parameter_outOfBound, "Param out of bounds!");
CCtxParams->ldmParams.hashRateLog = value;
return CCtxParams->ldmParams.hashRateLog;
@@ -821,8 +831,11 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
{
DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
- RETURN_ERROR_IF(cctx->cdict, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "The context is in the wrong stage!");
+ RETURN_ERROR_IF(cctx->cdict, stage_wrong,
+ "Can't override parameters with cdict attached (some must "
+ "be inherited from the cdict).");
cctx->requestedParams = *params;
return 0;
@@ -831,7 +844,8 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize);
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't set pledgedSrcSize when not in init stage.");
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
return 0;
}
@@ -845,7 +859,7 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
{
ZSTD_localDict* const dl = &cctx->localDict;
ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(
- &cctx->requestedParams, 0, dl->dictSize);
+ &cctx->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN, dl->dictSize);
if (dl->dict == NULL) {
/* No local dictionary. */
assert(dl->dictBuffer == NULL);
@@ -869,7 +883,7 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
dl->dictContentType,
cParams,
cctx->customMem);
- RETURN_ERROR_IF(!dl->cdict, memory_allocation);
+ RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed");
cctx->cdict = dl->cdict;
return 0;
}
@@ -878,7 +892,8 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
{
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't load a dictionary when ctx is not in init stage.");
RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
"no malloc for static CCtx");
DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
@@ -889,7 +904,7 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
cctx->localDict.dict = dict;
} else {
void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem);
- RETURN_ERROR_IF(!dictBuffer, memory_allocation);
+ RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!");
memcpy(dictBuffer, dict, dictSize);
cctx->localDict.dictBuffer = dictBuffer;
cctx->localDict.dict = dictBuffer;
@@ -915,7 +930,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
{
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't ref a dict when ctx not in init stage.");
/* Free the existing local cdict (if any) to save memory. */
ZSTD_clearAllDicts(cctx);
cctx->cdict = cdict;
@@ -930,11 +946,14 @@ size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSiz
size_t ZSTD_CCtx_refPrefix_advanced(
ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
{
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't ref a prefix when ctx not in init stage.");
ZSTD_clearAllDicts(cctx);
- cctx->prefixDict.dict = prefix;
- cctx->prefixDict.dictSize = prefixSize;
- cctx->prefixDict.dictContentType = dictContentType;
+ if (prefix != NULL && prefixSize > 0) {
+ cctx->prefixDict.dict = prefix;
+ cctx->prefixDict.dictSize = prefixSize;
+ cctx->prefixDict.dictContentType = dictContentType;
+ }
return 0;
}
@@ -949,7 +968,8 @@ size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
}
if ( (reset == ZSTD_reset_parameters)
|| (reset == ZSTD_reset_session_and_parameters) ) {
- RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't reset parameters only when not in init stage.");
ZSTD_clearAllDicts(cctx);
return ZSTD_CCtxParams_reset(&cctx->requestedParams);
}
@@ -996,7 +1016,7 @@ ZSTD_clampCParams(ZSTD_compressionParameters cParams)
/** ZSTD_cycleLog() :
* condition for correct operation : hashLog > 1 */
-static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
+U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
{
U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
return hashLog - btScale;
@@ -1006,7 +1026,7 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
* optimize `cPar` for a specified input (`srcSize` and `dictSize`).
* mostly downsize to reduce memory consumption and initialization latency.
* `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
- * note : for the time being, `srcSize==0` means "unknown" too, for compatibility with older convention.
+ * note : `srcSize==0` means 0!
* condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
static ZSTD_compressionParameters
ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
@@ -1017,10 +1037,8 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
assert(ZSTD_checkCParams(cPar)==0);
- if (dictSize && (srcSize+1<2) /* ZSTD_CONTENTSIZE_UNKNOWN and 0 mean "unknown" */ )
- srcSize = minSrcSize; /* presumed small when there is a dictionary */
- else if (srcSize == 0)
- srcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* 0 == unknown : presumed large */
+ if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
+ srcSize = minSrcSize;
/* resize windowLog if input is small enough, to use less memory */
if ( (srcSize < maxWindowResize)
@@ -1049,9 +1067,13 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
size_t dictSize)
{
cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */
+ if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN;
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
}
+static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
+static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
+
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
{
@@ -1059,7 +1081,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
srcSizeHint = CCtxParams->srcSizeHint;
}
- cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
+ cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize);
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
@@ -1069,6 +1091,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
assert(!ZSTD_checkCParams(cParams));
+ /* srcSizeHint == 0 means 0 */
return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
}
@@ -1104,7 +1127,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
{
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
{ ZSTD_compressionParameters const cParams =
- ZSTD_getCParamsFromCCtxParams(params, 0, 0);
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
U32 const divider = (cParams.minMatch==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider;
@@ -1118,13 +1141,26 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq));
- size_t const neededSpace = entropySpace + blockStateSpace + tokenSpace +
- matchStateSize + ldmSpace + ldmSeqSpace;
+ /* estimateCCtxSize is for one-shot compression. So no buffers should
+ * be needed. However, we still allocate two 0-sized buffers, which can
+ * take space under ASAN. */
+ size_t const bufferSpace = ZSTD_cwksp_alloc_size(0)
+ + ZSTD_cwksp_alloc_size(0);
+
size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx));
- DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)cctxSpace);
+ size_t const neededSpace =
+ cctxSpace +
+ entropySpace +
+ blockStateSpace +
+ ldmSpace +
+ ldmSeqSpace +
+ matchStateSize +
+ tokenSpace +
+ bufferSpace;
+
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
- return cctxSpace + neededSpace;
+ return neededSpace;
}
}
@@ -1136,7 +1172,7 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
return ZSTD_estimateCCtxSize_usingCParams(cParams);
}
@@ -1155,7 +1191,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
{
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
{ ZSTD_compressionParameters const cParams =
- ZSTD_getCParamsFromCCtxParams(params, 0, 0);
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
@@ -1175,7 +1211,7 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
return ZSTD_estimateCStreamSize_usingCParams(cParams);
}
@@ -1243,7 +1279,7 @@ static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
assert(cParams1.strategy == cParams2.strategy);
}
-static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
+void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
{
int i;
for (i = 0; i < ZSTD_REP_NUM; ++i)
@@ -1320,10 +1356,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
if (forceResetIndex == ZSTDirp_reset) {
- memset(&ms->window, 0, sizeof(ms->window));
- ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
- ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
- ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
+ ZSTD_window_init(&ms->window);
ZSTD_cwksp_mark_tables_dirty(ws);
}
@@ -1416,13 +1449,13 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
- ZSTD_indexResetPolicy_e needsIndexReset = ZSTDirp_continue;
+ ZSTD_indexResetPolicy_e needsIndexReset = zc->initialized ? ZSTDirp_continue : ZSTDirp_reset;
if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
needsIndexReset = ZSTDirp_reset;
}
- ZSTD_cwksp_bump_oversized_duration(ws, 0);
+ if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
/* Check if workspace is large enough, alloc a new one if needed */
{ size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
@@ -1459,7 +1492,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
needsIndexReset = ZSTDirp_reset;
ZSTD_cwksp_free(ws, zc->customMem);
- FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem));
+ FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), "");
DEBUGLOG(5, "reserving object space");
/* Statically sized space.
@@ -1530,7 +1563,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
&params.cParams,
crp,
needsIndexReset,
- ZSTD_resetTarget_CCtx));
+ ZSTD_resetTarget_CCtx), "");
/* ldm hash table */
if (params.ldmParams.enableLdm) {
@@ -1541,11 +1574,13 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
zc->maxNbLdmSequences = maxNbLdmSeq;
- memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
+ ZSTD_window_init(&zc->ldmState.window);
ZSTD_window_clear(&zc->ldmState.window);
+ zc->ldmState.loadedDictEnd = 0;
}
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
+ zc->initialized = 1;
return 0;
}
@@ -1603,10 +1638,11 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
assert(windowLog != 0);
/* Resize working context table params for input only, since the dict
* has its own tables. */
+ /* pledgeSrcSize == 0 means 0! */
params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
params.cParams.windowLog = windowLog;
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
- ZSTDcrp_makeClean, zbuff));
+ ZSTDcrp_makeClean, zbuff), "");
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
}
@@ -1655,7 +1691,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
params.cParams = *cdict_cParams;
params.cParams.windowLog = windowLog;
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
- ZSTDcrp_leaveDirty, zbuff));
+ ZSTDcrp_leaveDirty, zbuff), "");
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
@@ -1736,7 +1772,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
ZSTD_buffered_policy_e zbuff)
{
DEBUGLOG(5, "ZSTD_copyCCtx_internal");
- RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong);
+ RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
+ "Can't copy a ctx that's not in init stage.");
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
{ ZSTD_CCtx_params params = dstCCtx->requestedParams;
@@ -1889,16 +1926,6 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par
/* See doc/zstd_compression_format.md for detailed format description */
-static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
-{
- U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
- RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
- dstSize_tooSmall);
- MEM_writeLE24(dst, cBlockHeader24);
- memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
- return ZSTD_blockHeaderSize + srcSize;
-}
-
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
{
const seqDef* const sequences = seqStorePtr->sequencesStart;
@@ -1921,19 +1948,14 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
}
-static int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
+/* ZSTD_useTargetCBlockSize():
+ * Returns if target compressed block size param is being used.
+ * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize.
+ * Returns 1 if true, 0 otherwise. */
+static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
{
- switch (cctxParams->literalCompressionMode) {
- case ZSTD_lcm_huffman:
- return 0;
- case ZSTD_lcm_uncompressed:
- return 1;
- default:
- assert(0 /* impossible: pre-validated */);
- /* fall-through */
- case ZSTD_lcm_auto:
- return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
- }
+ DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize);
+ return (cctxParams->targetCBlockSize != 0);
}
/* ZSTD_compressSequences_internal():
@@ -1979,14 +2001,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
literals, litSize,
entropyWorkspace, entropyWkspSize,
bmi2);
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed");
assert(cSize <= dstCapacity);
op += cSize;
}
/* Sequences Header */
RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
- dstSize_tooSmall);
+ dstSize_tooSmall, "Can't fit seq hdr in output buf!");
if (nbSeq < 128) {
*op++ = (BYTE)nbSeq;
} else if (nbSeq < LONGNBSEQ) {
@@ -2031,7 +2053,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
prevEntropy->fse.litlengthCTable,
sizeof(prevEntropy->fse.litlengthCTable),
entropyWorkspace, entropyWkspSize);
- FORWARD_IF_ERROR(countSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
if (LLtype == set_compressed)
lastNCount = op;
op += countSize;
@@ -2059,7 +2081,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
prevEntropy->fse.offcodeCTable,
sizeof(prevEntropy->fse.offcodeCTable),
entropyWorkspace, entropyWkspSize);
- FORWARD_IF_ERROR(countSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
if (Offtype == set_compressed)
lastNCount = op;
op += countSize;
@@ -2085,7 +2107,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
prevEntropy->fse.matchlengthCTable,
sizeof(prevEntropy->fse.matchlengthCTable),
entropyWorkspace, entropyWkspSize);
- FORWARD_IF_ERROR(countSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
if (MLtype == set_compressed)
lastNCount = op;
op += countSize;
@@ -2101,7 +2123,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
CTable_LitLength, llCodeTable,
sequences, nbSeq,
longOffsets, bmi2);
- FORWARD_IF_ERROR(bitstreamSize);
+ FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
op += bitstreamSize;
assert(op <= oend);
/* zstd versions <= 1.3.4 mistakenly report corruption when
@@ -2145,7 +2167,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
*/
if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
return 0; /* block not compressed */
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressSequences_internal failed");
/* Check compressibility */
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
@@ -2271,7 +2293,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
/* Updates ldmSeqStore.size */
FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,
&zc->appliedParams.ldmParams,
- src, srcSize));
+ src, srcSize), "");
/* Updates ldmSeqStore.pos */
lastLLSize =
ZSTD_ldm_blockCompress(&ldmSeqStore,
@@ -2347,7 +2369,7 @@ size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);
SeqCollector seqCollector;
- RETURN_ERROR_IF(dst == NULL, memory_allocation);
+ RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
seqCollector.collectSequences = 1;
seqCollector.seqStart = outSeqs;
@@ -2370,6 +2392,25 @@ static int ZSTD_isRLE(const BYTE *ip, size_t length) {
return 1;
}
+/* Returns true if the given block may be RLE.
+ * This is just a heuristic based on the compressibility.
+ * It may return both false positives and false negatives.
+ */
+static int ZSTD_maybeRLE(seqStore_t const* seqStore)
+{
+ size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
+ size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
+
+ return nbSeqs < 4 && nbLits < 10;
+}
+
+static void ZSTD_confirmRepcodesAndEntropyTables(ZSTD_CCtx* zc)
+{
+ ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
+ zc->blockState.prevCBlock = zc->blockState.nextCBlock;
+ zc->blockState.nextCBlock = tmp;
+}
+
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 frame)
@@ -2387,7 +2428,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
(unsigned)zc->blockState.matchState.nextToUpdate);
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
- FORWARD_IF_ERROR(bss);
+ FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
}
@@ -2420,10 +2461,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
out:
if (!ZSTD_isError(cSize) && cSize > 1) {
- /* confirm repcodes and entropy tables when emitting a compressed block */
- ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
- zc->blockState.prevCBlock = zc->blockState.nextCBlock;
- zc->blockState.nextCBlock = tmp;
+ ZSTD_confirmRepcodesAndEntropyTables(zc);
}
/* We check that dictionaries have offset codes available for the first
* block. After the first block, the offcode table might not have large
@@ -2435,6 +2473,80 @@ out:
return cSize;
}
+static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const size_t bss, U32 lastBlock)
+{
+ DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()");
+ if (bss == ZSTDbss_compress) {
+ if (/* We don't want to emit our first block as a RLE even if it qualifies because
+ * doing so will cause the decoder (cli only) to throw a "should consume all input error."
+ * This is only an issue for zstd <= v1.4.3
+ */
+ !zc->isFirstBlock &&
+ ZSTD_maybeRLE(&zc->seqStore) &&
+ ZSTD_isRLE((BYTE const*)src, srcSize))
+ {
+ return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock);
+ }
+ /* Attempt superblock compression.
+ *
+ * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the
+ * standard ZSTD_compressBound(). This is a problem, because even if we have
+ * space now, taking an extra byte now could cause us to run out of space later
+ * and violate ZSTD_compressBound().
+ *
+ * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize.
+ *
+ * In order to respect ZSTD_compressBound() we must attempt to emit a raw
+ * uncompressed block in these cases:
+ * * cSize == 0: Return code for an uncompressed block.
+ * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize).
+ * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of
+ * output space.
+ * * cSize >= blockBound(srcSize): We have expanded the block too much so
+ * emit an uncompressed block.
+ */
+ {
+ size_t const cSize = ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock);
+ if (cSize != ERROR(dstSize_tooSmall)) {
+ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed");
+ if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) {
+ ZSTD_confirmRepcodesAndEntropyTables(zc);
+ return cSize;
+ }
+ }
+ }
+ }
+
+ DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()");
+ /* Superblock compression failed, attempt to emit a single no compress block.
+ * The decoder will be able to stream this block since it is uncompressed.
+ */
+ return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
+}
+
+static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ U32 lastBlock)
+{
+ size_t cSize = 0;
+ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
+ DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)",
+ (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize);
+ FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
+
+ cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed");
+
+ if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
+ zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
+
+ return cSize;
+}
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
ZSTD_cwksp* ws,
@@ -2478,6 +2590,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 <= ZSTD_WINDOWLOG_MAX);
DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
@@ -2500,21 +2613,31 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
/* 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,
- op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
- ip, blockSize, 1 /* frame */);
- FORWARD_IF_ERROR(cSize);
- if (cSize == 0) { /* block is not compressible */
- cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
- FORWARD_IF_ERROR(cSize);
+ { size_t cSize;
+ if (ZSTD_useTargetCBlockSize(&cctx->appliedParams)) {
+ cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed");
+ assert(cSize > 0);
+ assert(cSize <= blockSize + ZSTD_blockHeaderSize);
} else {
- const U32 cBlockHeader = cSize == 1 ?
- lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
- lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
- MEM_writeLE24(op, cBlockHeader);
- cSize += ZSTD_blockHeaderSize;
+ cSize = ZSTD_compressBlock_internal(cctx,
+ op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
+ ip, blockSize, 1 /* frame */);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed");
+
+ if (cSize == 0) { /* block is not compressible */
+ cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
+ FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
+ } else {
+ U32 const cBlockHeader = cSize == 1 ?
+ lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
+ lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
+ MEM_writeLE24(op, cBlockHeader);
+ cSize += ZSTD_blockHeaderSize;
+ }
}
+
ip += blockSize;
assert(remaining >= blockSize);
remaining -= blockSize;
@@ -2546,7 +2669,8 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
size_t pos=0;
assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
- RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);
+ RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall,
+ "dst buf is too small to fit worst-case frame header size.");
DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
!params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
@@ -2582,7 +2706,8 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
*/
size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
{
- RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall);
+ RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall,
+ "dst buf is too small to write frame trailer empty block.");
{ U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1); /* 0 size */
MEM_writeLE24(dst, cBlockHeader24);
return ZSTD_blockHeaderSize;
@@ -2591,9 +2716,11 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
{
- RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong);
+ RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong,
+ "wrong cctx stage");
RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm,
- parameter_unsupported);
+ parameter_unsupported,
+ "incompatible with ldm");
cctx->externSeqStore.seq = seq;
cctx->externSeqStore.size = nbSeq;
cctx->externSeqStore.capacity = nbSeq;
@@ -2618,7 +2745,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (frame && (cctx->stage==ZSTDcs_init)) {
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
- FORWARD_IF_ERROR(fhSize);
+ FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
assert(fhSize <= dstCapacity);
dstCapacity -= fhSize;
dst = (char*)dst + fhSize;
@@ -2645,7 +2772,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
{ size_t const cSize = frame ?
ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed");
cctx->consumedSrcSize += srcSize;
cctx->producedCSize += (cSize + fhSize);
assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
@@ -2682,7 +2809,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
{
DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
{ size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
- RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }
+ RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); }
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
}
@@ -2691,6 +2818,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
* @return : 0, or an error code
*/
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
+ ldmState_t* ls,
ZSTD_cwksp* ws,
ZSTD_CCtx_params const* params,
const void* src, size_t srcSize,
@@ -2702,6 +2830,11 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
ZSTD_window_update(&ms->window, src, srcSize);
ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
+ if (params->ldmParams.enableLdm && ls != NULL) {
+ ZSTD_window_update(&ls->window, src, srcSize);
+ ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
+ }
+
/* Assert that we the ms params match the params we're being given */
ZSTD_assertEqualCParams(params->cParams, ms->cParams);
@@ -2714,6 +2847,9 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);
+ if (params->ldmParams.enableLdm && ls != NULL)
+ ZSTD_ldm_fillHashTable(ls, (const BYTE*)src, (const BYTE*)src + srcSize, &params->ldmParams);
+
switch(params->cParams.strategy)
{
case ZSTD_fast:
@@ -2756,102 +2892,123 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
NOTE: This behavior is not standard and could be improved in the future. */
static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
U32 s;
- RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted);
+ RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted, "dict fse tables don't have all symbols");
for (s = 0; s <= maxSymbolValue; ++s) {
- RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted);
+ RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted, "dict fse tables don't have all symbols");
}
return 0;
}
-
-/* Dictionary format :
- * See :
- * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
- */
-/*! ZSTD_loadZstdDictionary() :
- * @return : dictID, or an error code
- * assumptions : magic number supposed already checked
- * dictSize supposed >= 8
- */
-static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
- ZSTD_matchState_t* ms,
- ZSTD_cwksp* ws,
- ZSTD_CCtx_params const* params,
- const void* dict, size_t dictSize,
- ZSTD_dictTableLoadMethod_e dtlm,
- void* workspace)
+size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
+ short* offcodeNCount, unsigned* offcodeMaxValue,
+ const void* const dict, size_t dictSize)
{
- const BYTE* dictPtr = (const BYTE*)dict;
+ const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */
const BYTE* const dictEnd = dictPtr + dictSize;
- short offcodeNCount[MaxOff+1];
- unsigned offcodeMaxValue = MaxOff;
- size_t dictID;
+ dictPtr += 8;
+ bs->entropy.huf.repeatMode = HUF_repeat_check;
- ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
- assert(dictSize >= 8);
- assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
+ { unsigned maxSymbolValue = 255;
+ unsigned hasZeroWeights = 1;
+ size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
+ dictEnd-dictPtr, &hasZeroWeights);
- dictPtr += 4; /* skip magic number */
- dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
- dictPtr += 4;
+ /* We only set the loaded table as valid if it contains all non-zero
+ * weights. Otherwise, we set it to check */
+ if (!hasZeroWeights)
+ bs->entropy.huf.repeatMode = HUF_repeat_valid;
- { unsigned maxSymbolValue = 255;
- size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted);
+ RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted, "");
dictPtr += hufHeaderSize;
}
{ unsigned offcodeLog;
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
+ RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
/* fill all offset symbols to avoid garbage at end of table */
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.offcodeCTable,
offcodeNCount, MaxOff, offcodeLog,
workspace, HUF_WORKSPACE_SIZE)),
- dictionary_corrupted);
+ dictionary_corrupted, "");
dictPtr += offcodeHeaderSize;
}
{ short matchlengthNCount[MaxML+1];
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
+ RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
/* Every match length code must have non-zero probability */
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
+ FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML), "");
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.matchlengthCTable,
matchlengthNCount, matchlengthMaxValue, matchlengthLog,
workspace, HUF_WORKSPACE_SIZE)),
- dictionary_corrupted);
+ dictionary_corrupted, "");
dictPtr += matchlengthHeaderSize;
}
{ short litlengthNCount[MaxLL+1];
unsigned litlengthMaxValue = MaxLL, litlengthLog;
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
+ RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
/* Every literal length code must have non-zero probability */
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
+ FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL), "");
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.litlengthCTable,
litlengthNCount, litlengthMaxValue, litlengthLog,
workspace, HUF_WORKSPACE_SIZE)),
- dictionary_corrupted);
+ dictionary_corrupted, "");
dictPtr += litlengthHeaderSize;
}
- RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
+ RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
bs->rep[0] = MEM_readLE32(dictPtr+0);
bs->rep[1] = MEM_readLE32(dictPtr+4);
bs->rep[2] = MEM_readLE32(dictPtr+8);
dictPtr += 12;
+ return dictPtr - (const BYTE*)dict;
+}
+
+/* Dictionary format :
+ * See :
+ * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
+ */
+/*! ZSTD_loadZstdDictionary() :
+ * @return : dictID, or an error code
+ * assumptions : magic number supposed already checked
+ * dictSize supposed >= 8
+ */
+static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
+ ZSTD_matchState_t* ms,
+ ZSTD_cwksp* ws,
+ ZSTD_CCtx_params const* params,
+ const void* dict, size_t dictSize,
+ ZSTD_dictTableLoadMethod_e dtlm,
+ void* workspace)
+{
+ const BYTE* dictPtr = (const BYTE*)dict;
+ const BYTE* const dictEnd = dictPtr + dictSize;
+ short offcodeNCount[MaxOff+1];
+ unsigned offcodeMaxValue = MaxOff;
+ size_t dictID;
+ size_t eSize;
+
+ ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
+ assert(dictSize >= 8);
+ assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
+
+ dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ );
+ eSize = ZSTD_loadCEntropy(bs, workspace, offcodeNCount, &offcodeMaxValue, dict, dictSize);
+ FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed");
+ dictPtr += eSize;
+
{ size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
U32 offcodeMax = MaxOff;
if (dictContentSize <= ((U32)-1) - 128 KB) {
@@ -2859,20 +3016,19 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
}
/* All offset values <= dictContentSize + 128 KB must be representable */
- FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
+ FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)), "");
/* All repCodes must be <= dictContentSize and != 0*/
{ U32 u;
for (u=0; u<3; u++) {
- RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted);
- RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted);
+ RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
+ RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
} }
- bs->entropy.huf.repeatMode = HUF_repeat_valid;
bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
- ms, ws, params, dictPtr, dictContentSize, dtlm));
+ ms, NULL, ws, params, dictPtr, dictContentSize, dtlm), "");
return dictID;
}
}
@@ -2882,6 +3038,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
static size_t
ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
ZSTD_matchState_t* ms,
+ ldmState_t* ls,
ZSTD_cwksp* ws,
const ZSTD_CCtx_params* params,
const void* dict, size_t dictSize,
@@ -2891,7 +3048,7 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
{
DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
if ((dict==NULL) || (dictSize<8)) {
- RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
+ RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
return 0;
}
@@ -2899,15 +3056,15 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
/* dict restricted modes */
if (dictContentType == ZSTD_dct_rawContent)
- return ZSTD_loadDictionaryContent(ms, ws, params, dict, dictSize, dtlm);
+ return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm);
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
if (dictContentType == ZSTD_dct_auto) {
DEBUGLOG(4, "raw content dictionary detected");
return ZSTD_loadDictionaryContent(
- ms, ws, params, dict, dictSize, dtlm);
+ ms, ls, ws, params, dict, dictSize, dtlm);
}
- RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
+ RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
assert(0); /* impossible */
}
@@ -2944,17 +3101,18 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
}
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
- ZSTDcrp_makeClean, zbuff) );
+ ZSTDcrp_makeClean, zbuff) , "");
{ size_t const dictID = cdict ?
ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
- &cctx->workspace, params, cdict->dictContent, cdict->dictContentSize,
- dictContentType, dtlm, cctx->entropyWorkspace)
+ &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
+ cdict->dictContentSize, dictContentType, dtlm,
+ cctx->entropyWorkspace)
: ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
- &cctx->workspace, params, dict, dictSize,
+ &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
dictContentType, dtlm, cctx->entropyWorkspace);
- FORWARD_IF_ERROR(dictID);
+ FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
assert(dictID <= UINT_MAX);
cctx->dictID = (U32)dictID;
}
@@ -2971,7 +3129,7 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
{
DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog);
/* compression parameters verification and optimization */
- FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) );
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , "");
return ZSTD_compressBegin_internal(cctx,
dict, dictSize, dictContentType, dtlm,
cdict,
@@ -2986,7 +3144,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params const cctxParams =
- ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
+ ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
return ZSTD_compressBegin_advanced_internal(cctx,
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
NULL /*cdict*/,
@@ -2995,9 +3153,9 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
ZSTD_CCtx_params const cctxParams =
- ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
+ ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
@@ -3024,7 +3182,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
/* special case : empty frame */
if (cctx->stage == ZSTDcs_init) {
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
- FORWARD_IF_ERROR(fhSize);
+ FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
dstCapacity -= fhSize;
op += fhSize;
cctx->stage = ZSTDcs_ongoing;
@@ -3033,7 +3191,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
if (cctx->stage != ZSTDcs_ending) {
/* write one last empty block, make it the "last" block */
U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
- RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for epilogue");
MEM_writeLE32(op, cBlockHeader24);
op += ZSTD_blockHeaderSize;
dstCapacity -= ZSTD_blockHeaderSize;
@@ -3041,7 +3199,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
if (cctx->appliedParams.fParams.checksumFlag) {
U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
- RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
MEM_writeLE32(op, checksum);
op += 4;
@@ -3059,9 +3217,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
size_t const cSize = ZSTD_compressContinue_internal(cctx,
dst, dstCapacity, src, srcSize,
1 /* frame mode */, 1 /* last chunk */);
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed");
endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
- FORWARD_IF_ERROR(endResult);
+ FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed");
assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
@@ -3081,7 +3239,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
const void* dict,size_t dictSize,
- ZSTD_parameters params)
+ const ZSTD_parameters* params)
{
ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
@@ -3100,12 +3258,12 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
ZSTD_parameters params)
{
DEBUGLOG(4, "ZSTD_compress_advanced");
- FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams));
+ FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
return ZSTD_compress_internal(cctx,
dst, dstCapacity,
src, srcSize,
dict, dictSize,
- params);
+ &params);
}
/* Internal */
@@ -3119,7 +3277,7 @@ size_t ZSTD_compress_advanced_internal(
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
- params, srcSize, ZSTDb_not_buffered) );
+ params, srcSize, ZSTDb_not_buffered) , "");
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
@@ -3129,8 +3287,9 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
int compressionLevel)
{
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
- ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0);
+ ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
+ DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
assert(params.fParams.contentSizeFlag == 1);
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
}
@@ -3176,7 +3335,7 @@ size_t ZSTD_estimateCDictSize_advanced(
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
}
@@ -3203,7 +3362,7 @@ static size_t ZSTD_initCDict_internal(
cdict->dictContent = dictBuffer;
} else {
void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
- RETURN_ERROR_IF(!internalBuffer, memory_allocation);
+ RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
cdict->dictContent = internalBuffer;
memcpy(internalBuffer, dictBuffer, dictSize);
}
@@ -3220,7 +3379,7 @@ static size_t ZSTD_initCDict_internal(
&cParams,
ZSTDcrp_makeClean,
ZSTDirp_reset,
- ZSTD_resetTarget_CDict));
+ ZSTD_resetTarget_CDict), "");
/* (Maybe) load the dictionary
* Skips loading the dictionary if it is < 8 bytes.
*/
@@ -3230,10 +3389,10 @@ static size_t ZSTD_initCDict_internal(
params.fParams.contentSizeFlag = 1;
params.cParams = cParams;
{ size_t const dictID = ZSTD_compress_insertDictionary(
- &cdict->cBlockState, &cdict->matchState, &cdict->workspace,
+ &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace,
&params, cdict->dictContent, cdict->dictContentSize,
dictContentType, ZSTD_dtlm_full, cdict->entropyWorkspace);
- FORWARD_IF_ERROR(dictID);
+ FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
assert(dictID <= (size_t)(U32)-1);
cdict->dictID = (U32)dictID;
}
@@ -3287,7 +3446,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,
ZSTD_dlm_byCopy, ZSTD_dct_auto,
cParams, ZSTD_defaultCMem);
@@ -3298,7 +3457,7 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
return ZSTD_createCDict_advanced(dict, dictSize,
ZSTD_dlm_byRef, ZSTD_dct_auto,
cParams, ZSTD_defaultCMem);
@@ -3381,7 +3540,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
- RETURN_ERROR_IF(cdict==NULL, dictionary_wrong);
+ RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!");
{ ZSTD_CCtx_params params = cctx->requestedParams;
params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
|| pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
@@ -3425,7 +3584,7 @@ size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
const void* src, size_t srcSize,
const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
{
- FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize)); /* will check if cdict != NULL */
+ FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
@@ -3497,7 +3656,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
dict, dictSize, dictContentType, ZSTD_dtlm_fast,
cdict,
&params, pledgedSrcSize,
- ZSTDb_buffered) );
+ ZSTDb_buffered) , "");
cctx->inToCompress = 0;
cctx->inBuffPos = 0;
@@ -3519,8 +3678,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
*/
U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
return 0;
}
@@ -3534,16 +3693,16 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_initCStream_internal");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
zcs->requestedParams = *params;
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
if (dict) {
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
} else {
/* Dictionary is cleared if !cdict */
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
}
return 0;
}
@@ -3556,10 +3715,10 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
zcs->requestedParams.fParams = fParams;
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
return 0;
}
@@ -3567,8 +3726,8 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
{
DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
return 0;
}
@@ -3587,20 +3746,20 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
*/
U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
DEBUGLOG(4, "ZSTD_initCStream_advanced");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
- FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
- zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, params);
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
+ FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
+ zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, &params);
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
return 0;
}
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
{
DEBUGLOG(4, "ZSTD_initCStream_usingDict");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
- FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
return 0;
}
@@ -3612,19 +3771,19 @@ size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigne
*/
U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
DEBUGLOG(4, "ZSTD_initCStream_srcSize");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
return 0;
}
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
{
DEBUGLOG(4, "ZSTD_initCStream");
- FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );
- FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );
+ FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , "");
+ FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) , "");
return 0;
}
@@ -3637,14 +3796,6 @@ static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
return hintInSize;
}
-static size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
- const void* src, size_t srcSize)
-{
- size_t const length = MIN(dstCapacity, srcSize);
- if (length) memcpy(dst, src, length);
- return length;
-}
-
/** ZSTD_compressStream_generic():
* internal function for all *compressStream*() variants
* non-static, because can be called from zstdmt_compress.c
@@ -3655,11 +3806,11 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
ZSTD_EndDirective const flushMode)
{
const char* const istart = (const char*)input->src;
- const char* const iend = istart + input->size;
- const char* ip = istart + input->pos;
+ const char* const iend = input->size != 0 ? istart + input->size : istart;
+ const char* ip = input->pos != 0 ? istart + input->pos : istart;
char* const ostart = (char*)output->dst;
- char* const oend = ostart + output->size;
- char* op = ostart + output->pos;
+ char* const oend = output->size != 0 ? ostart + output->size : ostart;
+ char* op = output->pos != 0 ? ostart + output->pos : ostart;
U32 someMoreWork = 1;
/* check expectations */
@@ -3685,7 +3836,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
size_t const cSize = ZSTD_compressEnd(zcs,
op, oend-op, ip, iend-ip);
DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
ip = iend;
op += cSize;
zcs->frameEnded = 1;
@@ -3698,7 +3849,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
zcs->inBuff + zcs->inBuffPos, toLoad,
ip, iend-ip);
zcs->inBuffPos += loaded;
- ip += loaded;
+ if (loaded != 0)
+ ip += loaded;
if ( (flushMode == ZSTD_e_continue)
&& (zcs->inBuffPos < zcs->inBuffTarget) ) {
/* not enough input to fill full block : stop here */
@@ -3726,7 +3878,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
zcs->inBuff + zcs->inToCompress, iSize) :
ZSTD_compressContinue(zcs, cDst, oSize,
zcs->inBuff + zcs->inToCompress, iSize);
- FORWARD_IF_ERROR(cSize);
+ FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
zcs->frameEnded = lastBlock;
/* prepare next block */
zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
@@ -3758,7 +3910,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
(unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
- op += flushed;
+ if (flushed)
+ op += flushed;
zcs->outBuffFlushedSize += flushed;
if (toFlush!=flushed) {
/* flush not fully completed, presumably because dst is too small */
@@ -3802,7 +3955,7 @@ static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx)
size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
{
- FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );
+ FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) , "");
return ZSTD_nextInputSizeHint_MTorST(zcs);
}
@@ -3814,15 +3967,15 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
{
DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
/* check conditions */
- RETURN_ERROR_IF(output->pos > output->size, GENERIC);
- RETURN_ERROR_IF(input->pos > input->size, GENERIC);
+ RETURN_ERROR_IF(output->pos > output->size, GENERIC, "invalid buffer");
+ RETURN_ERROR_IF(input->pos > input->size, GENERIC, "invalid buffer");
assert(cctx!=NULL);
/* transparent initialization stage */
if (cctx->streamStage == zcss_init) {
ZSTD_CCtx_params params = cctx->requestedParams;
ZSTD_prefixDict const prefixDict = cctx->prefixDict;
- FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) ); /* Init the local dict if present. */
+ FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
@@ -3841,14 +3994,14 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
params.nbWorkers);
cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);
- RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation);
+ RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
}
/* mt compression */
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
cctx->mtctx,
- prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,
- cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
+ cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
cctx->streamStage = zcss_load;
cctx->appliedParams.nbWorkers = params.nbWorkers;
} else
@@ -3856,7 +4009,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
{ FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,
prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
cctx->cdict,
- params, cctx->pledgedSrcSizePlusOne-1) );
+ params, cctx->pledgedSrcSizePlusOne-1) , "");
assert(cctx->streamStage == zcss_load);
assert(cctx->appliedParams.nbWorkers == 0);
} }
@@ -3878,7 +4031,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
}
- FORWARD_IF_ERROR(flushMin);
+ FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
} while (forceMaxProgress && flushMin != 0 && output->pos < output->size);
DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
/* Either we don't require maximum forward progress, we've finished the
@@ -3888,7 +4041,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
return flushMin;
}
#endif
- FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) );
+ FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , "");
DEBUGLOG(5, "completed ZSTD_compressStream2");
return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
}
@@ -3912,6 +4065,7 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
+ DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
{ size_t oPos = 0;
size_t iPos = 0;
@@ -3919,10 +4073,10 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
dst, dstCapacity, &oPos,
src, srcSize, &iPos,
ZSTD_e_end);
- FORWARD_IF_ERROR(result);
+ FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed");
if (result != 0) { /* compression not completed, due to lack of output space */
assert(oPos == dstCapacity);
- RETURN_ERROR(dstSize_tooSmall);
+ RETURN_ERROR(dstSize_tooSmall, "");
}
assert(iPos == srcSize); /* all input is expected consumed */
return oPos;
@@ -3944,7 +4098,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
{
ZSTD_inBuffer input = { NULL, 0, 0 };
size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
- FORWARD_IF_ERROR( remainingToFlush );
+ FORWARD_IF_ERROR( remainingToFlush , "ZSTD_compressStream2 failed");
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;
@@ -4069,35 +4223,56 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
},
};
-/*! ZSTD_getCParams() :
+/*! ZSTD_getCParams_internal() :
* @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
- * Size values are optional, provide 0 if not known or unused */
-ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
+ * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
+ * Use dictSize == 0 for unknown or unused. */
+static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
{
- size_t const addedSize = srcSizeHint ? 0 : 500;
- U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : ZSTD_CONTENTSIZE_UNKNOWN; /* intentional overflow for srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN */
+ int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
+ size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
+ U64 const rSize = unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
int row = compressionLevel;
- DEBUGLOG(5, "ZSTD_getCParams (cLevel=%i)", compressionLevel);
+ DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel);
if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
{ ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel); /* acceleration factor */
- return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); /* refine parameters based on srcSize & dictSize */
+ /* refine parameters based on srcSize & dictSize */
+ return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
}
}
+/*! ZSTD_getCParams() :
+ * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
+ * Size values are optional, provide 0 if not known or unused */
+ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
+{
+ if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
+ return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
+}
+
/*! ZSTD_getParams() :
* same idea as ZSTD_getCParams()
* @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
* Fields of `ZSTD_frameParameters` are set to default values */
-ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
+static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
ZSTD_parameters params;
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
memset(&params, 0, sizeof(params));
params.cParams = cParams;
params.fParams.contentSizeFlag = 1;
return params;
}
+
+/*! ZSTD_getParams() :
+ * same idea as ZSTD_getCParams()
+ * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
+ * Fields of `ZSTD_frameParameters` are set to default values */
+ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
+ if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
+ return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize);
+}
diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h
index 14036f873f..db73f6ce21 100644
--- a/thirdparty/zstd/compress/zstd_compress_internal.h
+++ b/thirdparty/zstd/compress/zstd_compress_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -18,7 +18,7 @@
/*-*************************************
* Dependencies
***************************************/
-#include "zstd_internal.h"
+#include "../common/zstd_internal.h"
#include "zstd_cwksp.h"
#ifdef ZSTD_MULTITHREAD
# include "zstdmt_compress.h"
@@ -166,6 +166,7 @@ typedef struct {
typedef struct {
ZSTD_window_t window; /* State for the window round buffer management */
ldmEntry_t* hashTable;
+ U32 loadedDictEnd;
BYTE* bucketOffsets; /* Next position in bucket to insert entry */
U64 hashPower; /* Used to compute the rolling hash.
* Depends on ldmParams.minMatchLength */
@@ -249,6 +250,7 @@ struct ZSTD_CCtx_s {
size_t staticSize;
SeqCollector seqCollector;
int isFirstBlock;
+ int initialized;
seqStore_t seqStore; /* sequences storage ptrs */
ldmState_t ldmState; /* long distance matching state */
@@ -324,6 +326,31 @@ MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
}
+typedef struct repcodes_s {
+ U32 rep[3];
+} repcodes_t;
+
+MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
+{
+ repcodes_t newReps;
+ if (offset >= ZSTD_REP_NUM) { /* full offset */
+ newReps.rep[2] = rep[1];
+ newReps.rep[1] = rep[0];
+ newReps.rep[0] = offset - ZSTD_REP_MOVE;
+ } else { /* repcode */
+ U32 const repCode = offset + ll0;
+ if (repCode > 0) { /* note : if repCode==0, no change */
+ U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
+ newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];
+ newReps.rep[1] = rep[0];
+ newReps.rep[0] = currentOffset;
+ } else { /* repCode == 0 */
+ memcpy(&newReps, rep, sizeof(newReps));
+ }
+ }
+ return newReps;
+}
+
/* ZSTD_cParam_withinBounds:
* @return 1 if value is within cParam bounds,
* 0 otherwise */
@@ -336,6 +363,30 @@ MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
return 1;
}
+/* ZSTD_noCompressBlock() :
+ * Writes uncompressed block to dst buffer from given src.
+ * Returns the size of the block */
+MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
+{
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
+ RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
+ dstSize_tooSmall, "dst buf too small for uncompressed block");
+ MEM_writeLE24(dst, cBlockHeader24);
+ memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
+ return ZSTD_blockHeaderSize + srcSize;
+}
+
+MEM_STATIC size_t ZSTD_rleCompressBlock (void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock)
+{
+ BYTE* const op = (BYTE*)dst;
+ U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3);
+ RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, "");
+ MEM_writeLE24(op, cBlockHeader);
+ op[3] = src;
+ return 4;
+}
+
+
/* ZSTD_minGain() :
* minimum compression required
* to generate a compress block or a compressed literals section.
@@ -348,6 +399,21 @@ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
return (srcSize >> minlog) + 2;
}
+MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
+{
+ switch (cctxParams->literalCompressionMode) {
+ case ZSTD_lcm_huffman:
+ return 0;
+ case ZSTD_lcm_uncompressed:
+ return 1;
+ default:
+ assert(0 /* impossible: pre-validated */);
+ /* fall-through */
+ case ZSTD_lcm_auto:
+ return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
+ }
+}
+
/*! ZSTD_safecopyLiterals() :
* memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w.
* Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single
@@ -433,8 +499,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
if (MEM_64bits()) {
# if defined(_MSC_VER) && defined(_WIN64)
unsigned long r = 0;
- _BitScanForward64( &r, (U64)val );
- return (unsigned)(r>>3);
+ return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_ctzll((U64)val) >> 3);
# else
@@ -451,8 +516,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
} else { /* 32 bits */
# if defined(_MSC_VER)
unsigned long r=0;
- _BitScanForward( &r, (U32)val );
- return (unsigned)(r>>3);
+ return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3)
return (__builtin_ctz((U32)val) >> 3);
# else
@@ -467,8 +531,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
if (MEM_64bits()) {
# if defined(_MSC_VER) && defined(_WIN64)
unsigned long r = 0;
- _BitScanReverse64( &r, val );
- return (unsigned)(r>>3);
+ return _BitScanReverse64( &r, val ) ? (unsigned)(r >> 3) : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_clzll(val) >> 3);
# else
@@ -482,8 +545,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
} else { /* 32 bits */
# if defined(_MSC_VER)
unsigned long r = 0;
- _BitScanReverse( &r, (unsigned long)val );
- return (unsigned)(r>>3);
+ return _BitScanReverse( &r, (unsigned long)val ) ? (unsigned)(r >> 3) : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3)
return (__builtin_clz((U32)val) >> 3);
# else
@@ -730,7 +792,10 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
*/
U32 const cycleMask = (1U << cycleLog) - 1;
U32 const current = (U32)((BYTE const*)src - window->base);
- U32 const newCurrent = (current & cycleMask) + maxDist;
+ U32 const currentCycle0 = current & cycleMask;
+ /* Exclude zero so that newCurrent - maxDist >= 1. */
+ U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
+ U32 const newCurrent = currentCycle1 + maxDist;
U32 const correction = current - newCurrent;
assert((maxDist & cycleMask) == 0);
assert(current > newCurrent);
@@ -739,8 +804,17 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
window->base += correction;
window->dictBase += correction;
- window->lowLimit -= correction;
- window->dictLimit -= correction;
+ if (window->lowLimit <= correction) window->lowLimit = 1;
+ else window->lowLimit -= correction;
+ if (window->dictLimit <= correction) window->dictLimit = 1;
+ else window->dictLimit -= correction;
+
+ /* Ensure we can still reference the full window. */
+ assert(newCurrent >= maxDist);
+ assert(newCurrent - maxDist >= 1);
+ /* Ensure that lowLimit and dictLimit didn't underflow. */
+ assert(window->lowLimit <= newCurrent);
+ assert(window->dictLimit <= newCurrent);
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
window->lowLimit);
@@ -844,6 +918,15 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
} } }
}
+MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
+ memset(window, 0, sizeof(*window));
+ window->base = (BYTE const*)"";
+ window->dictBase = (BYTE const*)"";
+ window->dictLimit = 1; /* start from 1, so that 1st position is valid */
+ window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
+ window->nextSrc = window->base + 1; /* see issue #1241 */
+}
+
/**
* ZSTD_window_update():
* Updates the window by appending [src, src + srcSize) to the window.
@@ -857,6 +940,10 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
BYTE const* const ip = (BYTE const*)src;
U32 contiguous = 1;
DEBUGLOG(5, "ZSTD_window_update");
+ if (srcSize == 0)
+ return contiguous;
+ assert(window->base != NULL);
+ assert(window->dictBase != NULL);
/* Check if blocks follow each other */
if (src != window->nextSrc) {
/* not contiguous */
@@ -867,7 +954,7 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
window->dictLimit = (U32)distanceFromBase;
window->dictBase = window->base;
window->base = ip - distanceFromBase;
- // ms->nextToUpdate = window->dictLimit;
+ /* ms->nextToUpdate = window->dictLimit; */
if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */
contiguous = 0;
}
@@ -883,6 +970,9 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
return contiguous;
}
+/**
+ * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
+ */
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
{
U32 const maxDistance = 1U << windowLog;
@@ -893,6 +983,19 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current
return matchLowest;
}
+/**
+ * Returns the lowest allowed match index in the prefix.
+ */
+MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
+{
+ U32 const maxDistance = 1U << windowLog;
+ U32 const lowestValid = ms->window.dictLimit;
+ U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ U32 const isDictionary = (ms->loadedDictEnd != 0);
+ U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
+ return matchLowest;
+}
+
/* debug functions */
@@ -931,6 +1034,21 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
}
#endif
+/* ===============================================================
+ * Shared internal declarations
+ * These prototypes may be called from sources not in lib/compress
+ * =============================================================== */
+
+/* ZSTD_loadCEntropy() :
+ * dict : must point at beginning of a valid zstd dictionary.
+ * return : size of dictionary header (size of magic number + dict ID + entropy tables)
+ * assumptions : magic number supposed already checked
+ * and dictSize >= 8 */
+size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
+ short* offcodeNCount, unsigned* offcodeMaxValue,
+ const void* const dict, size_t dictSize);
+
+void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
/* ==============================================================
* Private declarations
@@ -940,6 +1058,7 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
/* ZSTD_getCParamsFromCCtxParams() :
* cParams are built depending on compressionLevel, src size hints,
* LDM and manually set compression parameters.
+ * Note: srcSizeHint == 0 means 0!
*/
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize);
@@ -999,5 +1118,8 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);
*/
size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);
+/** ZSTD_cycleLog() :
+ * condition for correct operation : hashLog > 1 */
+U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
#endif /* ZSTD_COMPRESS_H */
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.c b/thirdparty/zstd/compress/zstd_compress_literals.c
index 6c13331182..17e7168d89 100644
--- a/thirdparty/zstd/compress/zstd_compress_literals.c
+++ b/thirdparty/zstd/compress/zstd_compress_literals.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -18,7 +18,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
BYTE* const ostart = (BYTE* const)dst;
U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
- RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall);
+ RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, "");
switch(flSize)
{
@@ -36,6 +36,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
}
memcpy(ostart + flSize, src, srcSize);
+ DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
return srcSize + flSize;
}
@@ -62,6 +63,7 @@ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void*
}
ostart[flSize] = *(const BYTE*)src;
+ DEBUGLOG(5, "RLE literals: %u -> %u", (U32)srcSize, (U32)flSize + 1);
return flSize+1;
}
@@ -80,8 +82,8 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
symbolEncodingType_e hType = set_compressed;
size_t cLitSize;
- DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
- disableLiteralCompression);
+ DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i srcSize=%u)",
+ disableLiteralCompression, (U32)srcSize);
/* Prepare nextEntropy assuming reusing the existing table */
memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
@@ -102,14 +104,15 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
cLitSize = singleStream ?
HUF_compress1X_repeat(
ostart+lhSize, dstCapacity-lhSize, src, srcSize,
- 255, 11, entropyWorkspace, entropyWorkspaceSize,
+ HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
(HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) :
HUF_compress4X_repeat(
ostart+lhSize, dstCapacity-lhSize, src, srcSize,
- 255, 11, entropyWorkspace, entropyWorkspaceSize,
+ HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize,
(HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
if (repeat != HUF_repeat_none) {
/* reused the existing table */
+ DEBUGLOG(5, "Reusing previous huffman table");
hType = set_repeat;
}
}
@@ -150,5 +153,6 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
default: /* not possible : lhSize is {3,4,5} */
assert(0);
}
+ DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize));
return lhSize+cLitSize;
}
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.h b/thirdparty/zstd/compress/zstd_compress_literals.h
index 97273d7cfd..8b08705743 100644
--- a/thirdparty/zstd/compress/zstd_compress_literals.h
+++ b/thirdparty/zstd/compress/zstd_compress_literals.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.c b/thirdparty/zstd/compress/zstd_compress_sequences.c
index 0ff7a26823..f9f8097c83 100644
--- a/thirdparty/zstd/compress/zstd_compress_sequences.c
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -60,7 +60,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
BYTE wksp[FSE_NCOUNTBOUND];
S16 norm[MaxSeq + 1];
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), "");
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
}
@@ -86,7 +86,7 @@ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t
* Returns the cost in bits of encoding the distribution in count using ctable.
* Returns an error if ctable cannot represent all the symbols in count.
*/
-static size_t ZSTD_fseBitCost(
+size_t ZSTD_fseBitCost(
FSE_CTable const* ctable,
unsigned const* count,
unsigned const max)
@@ -96,18 +96,22 @@ static size_t ZSTD_fseBitCost(
unsigned s;
FSE_CState_t cstate;
FSE_initCState(&cstate, ctable);
- RETURN_ERROR_IF(ZSTD_getFSEMaxSymbolValue(ctable) < max, GENERIC,
- "Repeat FSE_CTable has maxSymbolValue %u < %u",
+ if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
+ DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
ZSTD_getFSEMaxSymbolValue(ctable), max);
+ return ERROR(GENERIC);
+ }
for (s = 0; s <= max; ++s) {
unsigned const tableLog = cstate.stateLog;
unsigned const badCost = (tableLog + 1) << kAccuracyLog;
unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
if (count[s] == 0)
continue;
- RETURN_ERROR_IF(bitCost >= badCost, GENERIC,
- "Repeat FSE_CTable has Prob[%u] == 0", s);
- cost += count[s] * bitCost;
+ if (bitCost >= badCost) {
+ DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
+ return ERROR(GENERIC);
+ }
+ cost += (size_t)count[s] * bitCost;
}
return cost >> kAccuracyLog;
}
@@ -117,15 +121,15 @@ static size_t ZSTD_fseBitCost(
* table described by norm. The max symbol support by norm is assumed >= max.
* norm must be valid for every symbol with non-zero probability in count.
*/
-static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
- unsigned const* count, unsigned const max)
+size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
+ unsigned const* count, unsigned const max)
{
unsigned const shift = 8 - accuracyLog;
size_t cost = 0;
unsigned s;
assert(accuracyLog <= 8);
for (s = 0; s <= max; ++s) {
- unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
+ unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1;
unsigned const norm256 = normAcc << shift;
assert(norm256 > 0);
assert(norm256 < 256);
@@ -230,15 +234,15 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
switch (type) {
case set_rle:
- FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max));
- RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall);
+ FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), "");
+ RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space");
*op = codeTable[0];
return 1;
case set_repeat:
memcpy(nextCTable, prevCTable, prevCTableSize);
return 0;
case set_basic:
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize)); /* note : could be pre-calculated */
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
return 0;
case set_compressed: {
S16 norm[MaxSeq + 1];
@@ -249,14 +253,14 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
nbSeq_1--;
}
assert(nbSeq_1 > 1);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max), "");
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
- FORWARD_IF_ERROR(NCountSize);
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize));
+ FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
return NCountSize;
}
}
- default: assert(0); RETURN_ERROR(GENERIC);
+ default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach");
}
}
@@ -290,7 +294,7 @@ ZSTD_encodeSequences_body(
if (MEM_32bits()) BIT_flushBits(&blockStream);
if (longOffsets) {
U32 const ofBits = ofCodeTable[nbSeq-1];
- int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
if (extraBits) {
BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
BIT_flushBits(&blockStream);
@@ -327,7 +331,7 @@ ZSTD_encodeSequences_body(
BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
if (longOffsets) {
- int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
if (extraBits) {
BIT_addBits(&blockStream, sequences[n].offset, extraBits);
BIT_flushBits(&blockStream); /* (7)*/
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.h b/thirdparty/zstd/compress/zstd_compress_sequences.h
index 57e8e367b0..68c6f9a5ac 100644
--- a/thirdparty/zstd/compress/zstd_compress_sequences.h
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -11,8 +11,8 @@
#ifndef ZSTD_COMPRESS_SEQUENCES_H
#define ZSTD_COMPRESS_SEQUENCES_H
-#include "fse.h" /* FSE_repeat, FSE_CTable */
-#include "zstd_internal.h" /* symbolEncodingType_e, ZSTD_strategy */
+#include "../common/fse.h" /* FSE_repeat, FSE_CTable */
+#include "../common/zstd_internal.h" /* symbolEncodingType_e, ZSTD_strategy */
typedef enum {
ZSTD_defaultDisallowed = 0,
@@ -44,4 +44,11 @@ size_t ZSTD_encodeSequences(
FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2);
+size_t ZSTD_fseBitCost(
+ FSE_CTable const* ctable,
+ unsigned const* count,
+ unsigned const max);
+
+size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
+ unsigned const* count, unsigned const max);
#endif /* ZSTD_COMPRESS_SEQUENCES_H */
diff --git a/thirdparty/zstd/compress/zstd_compress_superblock.c b/thirdparty/zstd/compress/zstd_compress_superblock.c
new file mode 100644
index 0000000000..b693866c0a
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_superblock.c
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+ /*-*************************************
+ * Dependencies
+ ***************************************/
+#include "zstd_compress_superblock.h"
+
+#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */
+#include "hist.h" /* HIST_countFast_wksp */
+#include "zstd_compress_internal.h"
+#include "zstd_compress_sequences.h"
+#include "zstd_compress_literals.h"
+
+/*-*************************************
+* Superblock entropy buffer structs
+***************************************/
+/** ZSTD_hufCTablesMetadata_t :
+ * Stores Literals Block Type for a super-block in hType, and
+ * huffman tree description in hufDesBuffer.
+ * hufDesSize refers to the size of huffman tree description in bytes.
+ * This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
+typedef struct {
+ symbolEncodingType_e hType;
+ BYTE hufDesBuffer[500]; /* TODO give name to this value */
+ size_t hufDesSize;
+} ZSTD_hufCTablesMetadata_t;
+
+/** ZSTD_fseCTablesMetadata_t :
+ * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
+ * fse tables in fseTablesBuffer.
+ * fseTablesSize refers to the size of fse tables in bytes.
+ * This metadata is populated in ZSTD_buildSuperBlockEntropy_sequences() */
+typedef struct {
+ symbolEncodingType_e llType;
+ symbolEncodingType_e ofType;
+ symbolEncodingType_e mlType;
+ BYTE fseTablesBuffer[500]; /* TODO give name to this value */
+ size_t fseTablesSize;
+ size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
+} ZSTD_fseCTablesMetadata_t;
+
+typedef struct {
+ ZSTD_hufCTablesMetadata_t hufMetadata;
+ ZSTD_fseCTablesMetadata_t fseMetadata;
+} ZSTD_entropyCTablesMetadata_t;
+
+
+/** ZSTD_buildSuperBlockEntropy_literal() :
+ * Builds entropy for the super-block literals.
+ * Stores literals block type (raw, rle, compressed, repeat) and
+ * huffman description table to hufMetadata.
+ * @return : size of huffman description table or error code */
+static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSize,
+ const ZSTD_hufCTables_t* prevHuf,
+ ZSTD_hufCTables_t* nextHuf,
+ ZSTD_hufCTablesMetadata_t* hufMetadata,
+ const int disableLiteralsCompression,
+ void* workspace, size_t wkspSize)
+{
+ BYTE* const wkspStart = (BYTE*)workspace;
+ BYTE* const wkspEnd = wkspStart + wkspSize;
+ BYTE* const countWkspStart = wkspStart;
+ unsigned* const countWksp = (unsigned*)workspace;
+ const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
+ BYTE* const nodeWksp = countWkspStart + countWkspSize;
+ const size_t nodeWkspSize = wkspEnd-nodeWksp;
+ unsigned maxSymbolValue = 255;
+ unsigned huffLog = HUF_TABLELOG_DEFAULT;
+ HUF_repeat repeat = prevHuf->repeatMode;
+
+ DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
+
+ /* Prepare nextEntropy assuming reusing the existing table */
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+
+ if (disableLiteralsCompression) {
+ DEBUGLOG(5, "set_basic - disabled");
+ hufMetadata->hType = set_basic;
+ return 0;
+ }
+
+ /* small ? don't even attempt compression (speed opt) */
+# define COMPRESS_LITERALS_SIZE_MIN 63
+ { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
+ if (srcSize <= minLitSize) {
+ DEBUGLOG(5, "set_basic - too small");
+ hufMetadata->hType = set_basic;
+ return 0;
+ }
+ }
+
+ /* Scan input and build symbol stats */
+ { size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
+ FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
+ if (largest == srcSize) {
+ DEBUGLOG(5, "set_rle");
+ hufMetadata->hType = set_rle;
+ return 0;
+ }
+ if (largest <= (srcSize >> 7)+4) {
+ DEBUGLOG(5, "set_basic - no gain");
+ hufMetadata->hType = set_basic;
+ return 0;
+ }
+ }
+
+ /* Validate the previous Huffman table */
+ if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
+ repeat = HUF_repeat_none;
+ }
+
+ /* Build Huffman Tree */
+ memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
+ huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
+ { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
+ maxSymbolValue, huffLog,
+ nodeWksp, nodeWkspSize);
+ FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
+ huffLog = (U32)maxBits;
+ { /* Build and write the CTable */
+ size_t const newCSize = HUF_estimateCompressedSize(
+ (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
+ size_t const hSize = HUF_writeCTable(
+ hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
+ (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog);
+ /* Check against repeating the previous CTable */
+ if (repeat != HUF_repeat_none) {
+ size_t const oldCSize = HUF_estimateCompressedSize(
+ (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
+ if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
+ DEBUGLOG(5, "set_repeat - smaller");
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ hufMetadata->hType = set_repeat;
+ return 0;
+ }
+ }
+ if (newCSize + hSize >= srcSize) {
+ DEBUGLOG(5, "set_basic - no gains");
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ hufMetadata->hType = set_basic;
+ return 0;
+ }
+ DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
+ hufMetadata->hType = set_compressed;
+ nextHuf->repeatMode = HUF_repeat_check;
+ return hSize;
+ }
+ }
+}
+
+/** ZSTD_buildSuperBlockEntropy_sequences() :
+ * Builds entropy for the super-block sequences.
+ * Stores symbol compression modes and fse table to fseMetadata.
+ * @return : size of fse tables or error code */
+static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
+ const ZSTD_fseCTables_t* prevEntropy,
+ ZSTD_fseCTables_t* nextEntropy,
+ const ZSTD_CCtx_params* cctxParams,
+ ZSTD_fseCTablesMetadata_t* fseMetadata,
+ void* workspace, size_t wkspSize)
+{
+ BYTE* const wkspStart = (BYTE*)workspace;
+ BYTE* const wkspEnd = wkspStart + wkspSize;
+ BYTE* const countWkspStart = wkspStart;
+ unsigned* const countWksp = (unsigned*)workspace;
+ const size_t countWkspSize = (MaxSeq + 1) * sizeof(unsigned);
+ BYTE* const cTableWksp = countWkspStart + countWkspSize;
+ const size_t cTableWkspSize = wkspEnd-cTableWksp;
+ ZSTD_strategy const strategy = cctxParams->cParams.strategy;
+ FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
+ FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
+ FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
+ const BYTE* const ofCodeTable = seqStorePtr->ofCode;
+ const BYTE* const llCodeTable = seqStorePtr->llCode;
+ const BYTE* const mlCodeTable = seqStorePtr->mlCode;
+ size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
+ BYTE* const ostart = fseMetadata->fseTablesBuffer;
+ BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
+ BYTE* op = ostart;
+
+ assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
+ DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
+ memset(workspace, 0, wkspSize);
+
+ fseMetadata->lastCountSize = 0;
+ /* convert length/distances into codes */
+ ZSTD_seqToCodes(seqStorePtr);
+ /* build CTable for Literal Lengths */
+ { U32 LLtype;
+ unsigned max = MaxLL;
+ size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
+ DEBUGLOG(5, "Building LL table");
+ nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
+ LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
+ countWksp, max, mostFrequent, nbSeq,
+ LLFSELog, prevEntropy->litlengthCTable,
+ LL_defaultNorm, LL_defaultNormLog,
+ ZSTD_defaultAllowed, strategy);
+ assert(set_basic < set_compressed && set_rle < set_compressed);
+ assert(!(LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
+ { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
+ countWksp, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
+ prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
+ cTableWksp, cTableWkspSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
+ if (LLtype == set_compressed)
+ fseMetadata->lastCountSize = countSize;
+ op += countSize;
+ fseMetadata->llType = (symbolEncodingType_e) LLtype;
+ } }
+ /* build CTable for Offsets */
+ { U32 Offtype;
+ unsigned max = MaxOff;
+ size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
+ /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
+ ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
+ DEBUGLOG(5, "Building OF table");
+ nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
+ Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
+ countWksp, max, mostFrequent, nbSeq,
+ OffFSELog, prevEntropy->offcodeCTable,
+ OF_defaultNorm, OF_defaultNormLog,
+ defaultPolicy, strategy);
+ assert(!(Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
+ { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
+ countWksp, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
+ prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
+ cTableWksp, cTableWkspSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
+ if (Offtype == set_compressed)
+ fseMetadata->lastCountSize = countSize;
+ op += countSize;
+ fseMetadata->ofType = (symbolEncodingType_e) Offtype;
+ } }
+ /* build CTable for MatchLengths */
+ { U32 MLtype;
+ unsigned max = MaxML;
+ size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
+ DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
+ nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
+ MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
+ countWksp, max, mostFrequent, nbSeq,
+ MLFSELog, prevEntropy->matchlengthCTable,
+ ML_defaultNorm, ML_defaultNormLog,
+ ZSTD_defaultAllowed, strategy);
+ assert(!(MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
+ { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
+ countWksp, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
+ prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
+ cTableWksp, cTableWkspSize);
+ FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
+ if (MLtype == set_compressed)
+ fseMetadata->lastCountSize = countSize;
+ op += countSize;
+ fseMetadata->mlType = (symbolEncodingType_e) MLtype;
+ } }
+ assert((size_t) (op-ostart) <= sizeof(fseMetadata->fseTablesBuffer));
+ return op-ostart;
+}
+
+
+/** ZSTD_buildSuperBlockEntropy() :
+ * Builds entropy for the super-block.
+ * @return : 0 on success or error code */
+static size_t
+ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
+ const ZSTD_entropyCTables_t* prevEntropy,
+ ZSTD_entropyCTables_t* nextEntropy,
+ const ZSTD_CCtx_params* cctxParams,
+ ZSTD_entropyCTablesMetadata_t* entropyMetadata,
+ void* workspace, size_t wkspSize)
+{
+ size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
+ DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy");
+ entropyMetadata->hufMetadata.hufDesSize =
+ ZSTD_buildSuperBlockEntropy_literal(seqStorePtr->litStart, litSize,
+ &prevEntropy->huf, &nextEntropy->huf,
+ &entropyMetadata->hufMetadata,
+ ZSTD_disableLiteralsCompression(cctxParams),
+ workspace, wkspSize);
+ FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildSuperBlockEntropy_literal failed");
+ entropyMetadata->fseMetadata.fseTablesSize =
+ ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr,
+ &prevEntropy->fse, &nextEntropy->fse,
+ cctxParams,
+ &entropyMetadata->fseMetadata,
+ workspace, wkspSize);
+ FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildSuperBlockEntropy_sequences failed");
+ return 0;
+}
+
+/** ZSTD_compressSubBlock_literal() :
+ * Compresses literals section for a sub-block.
+ * When we have to write the Huffman table we will sometimes choose a header
+ * size larger than necessary. This is because we have to pick the header size
+ * before we know the table size + compressed size, so we have a bound on the
+ * table size. If we guessed incorrectly, we fall back to uncompressed literals.
+ *
+ * We write the header when writeEntropy=1 and set entropyWrriten=1 when we succeeded
+ * in writing the header, otherwise it is set to 0.
+ *
+ * hufMetadata->hType has literals block type info.
+ * If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block.
+ * If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block.
+ * If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block
+ * If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block
+ * and the following sub-blocks' literals sections will be Treeless_Literals_Block.
+ * @return : compressed size of literals section of a sub-block
+ * Or 0 if it unable to compress.
+ * Or error code */
+static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
+ const ZSTD_hufCTablesMetadata_t* hufMetadata,
+ const BYTE* literals, size_t litSize,
+ void* dst, size_t dstSize,
+ const int bmi2, int writeEntropy, int* entropyWritten)
+{
+ size_t const header = writeEntropy ? 200 : 0;
+ size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header));
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstSize;
+ BYTE* op = ostart + lhSize;
+ U32 const singleStream = lhSize == 3;
+ symbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat;
+ size_t cLitSize = 0;
+
+ (void)bmi2; /* TODO bmi2... */
+
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy);
+
+ *entropyWritten = 0;
+ if (litSize == 0 || hufMetadata->hType == set_basic) {
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal");
+ return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
+ } else if (hufMetadata->hType == set_rle) {
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal");
+ return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize);
+ }
+
+ assert(litSize > 0);
+ assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
+
+ if (writeEntropy && hufMetadata->hType == set_compressed) {
+ memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
+ op += hufMetadata->hufDesSize;
+ cLitSize += hufMetadata->hufDesSize;
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
+ }
+
+ /* TODO bmi2 */
+ { const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, oend-op, literals, litSize, hufTable)
+ : HUF_compress4X_usingCTable(op, oend-op, literals, litSize, hufTable);
+ op += cSize;
+ cLitSize += cSize;
+ if (cSize == 0 || ERR_isError(cSize)) {
+ DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize));
+ return 0;
+ }
+ /* If we expand and we aren't writing a header then emit uncompressed */
+ if (!writeEntropy && cLitSize >= litSize) {
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible");
+ return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
+ }
+ /* If we are writing headers then allow expansion that doesn't change our header size. */
+ if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) {
+ assert(cLitSize > litSize);
+ DEBUGLOG(5, "Literals expanded beyond allowed header size");
+ return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
+ }
+ DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize);
+ }
+
+ /* Build header */
+ switch(lhSize)
+ {
+ case 3: /* 2 - 2 - 10 - 10 */
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14);
+ MEM_writeLE24(ostart, lhc);
+ break;
+ }
+ case 4: /* 2 - 2 - 14 - 14 */
+ { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18);
+ MEM_writeLE32(ostart, lhc);
+ break;
+ }
+ case 5: /* 2 - 2 - 18 - 18 */
+ { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22);
+ MEM_writeLE32(ostart, lhc);
+ ostart[4] = (BYTE)(cLitSize >> 10);
+ break;
+ }
+ default: /* not possible : lhSize is {3,4,5} */
+ assert(0);
+ }
+ *entropyWritten = 1;
+ DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart));
+ return op-ostart;
+}
+
+static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef* sequences, size_t nbSeq, size_t litSize, int lastSequence) {
+ const seqDef* const sstart = sequences;
+ const seqDef* const send = sequences + nbSeq;
+ const seqDef* sp = sstart;
+ size_t matchLengthSum = 0;
+ size_t litLengthSum = 0;
+ while (send-sp > 0) {
+ ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
+ litLengthSum += seqLen.litLength;
+ matchLengthSum += seqLen.matchLength;
+ sp++;
+ }
+ assert(litLengthSum <= litSize);
+ if (!lastSequence) {
+ assert(litLengthSum == litSize);
+ }
+ return matchLengthSum + litSize;
+}
+
+/** ZSTD_compressSubBlock_sequences() :
+ * Compresses sequences section for a sub-block.
+ * fseMetadata->llType, fseMetadata->ofType, and fseMetadata->mlType have
+ * symbol compression modes for the super-block.
+ * The first successfully compressed block will have these in its header.
+ * We set entropyWritten=1 when we succeed in compressing the sequences.
+ * The following sub-blocks will always have repeat mode.
+ * @return : compressed size of sequences section of a sub-block
+ * Or 0 if it is unable to compress
+ * Or error code. */
+static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables,
+ const ZSTD_fseCTablesMetadata_t* fseMetadata,
+ const seqDef* sequences, size_t nbSeq,
+ const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
+ const ZSTD_CCtx_params* cctxParams,
+ void* dst, size_t dstCapacity,
+ const int bmi2, int writeEntropy, int* entropyWritten)
+{
+ const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstCapacity;
+ BYTE* op = ostart;
+ BYTE* seqHead;
+
+ DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets);
+
+ *entropyWritten = 0;
+ /* Sequences Header */
+ RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
+ dstSize_tooSmall, "");
+ if (nbSeq < 0x7F)
+ *op++ = (BYTE)nbSeq;
+ else if (nbSeq < LONGNBSEQ)
+ 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;
+ if (nbSeq==0) {
+ return op - ostart;
+ }
+
+ /* seqHead : flags for FSE encoding type */
+ seqHead = op++;
+
+ DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart));
+
+ if (writeEntropy) {
+ const U32 LLtype = fseMetadata->llType;
+ const U32 Offtype = fseMetadata->ofType;
+ const U32 MLtype = fseMetadata->mlType;
+ DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
+ *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
+ memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
+ op += fseMetadata->fseTablesSize;
+ } else {
+ const U32 repeat = set_repeat;
+ *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2));
+ }
+
+ { size_t const bitstreamSize = ZSTD_encodeSequences(
+ op, oend - op,
+ fseTables->matchlengthCTable, mlCode,
+ fseTables->offcodeCTable, ofCode,
+ fseTables->litlengthCTable, llCode,
+ sequences, nbSeq,
+ longOffsets, bmi2);
+ FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
+ op += bitstreamSize;
+ /* 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.
+ * This can happen when the last set_compressed table present is 2
+ * bytes and the bitstream is only one byte.
+ * In this exceedingly rare case, we will simply emit an uncompressed
+ * block, since it isn't worth optimizing.
+ */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) {
+ /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
+ assert(fseMetadata->lastCountSize + bitstreamSize == 3);
+ DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
+ "emitting an uncompressed block.");
+ return 0;
+ }
+#endif
+ DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize);
+ }
+
+ /* zstd versions <= 1.4.0 mistakenly report error when
+ * sequences section body size is less than 3 bytes.
+ * Fixed by https://github.com/facebook/zstd/pull/1664.
+ * This can happen when the previous sequences section block is compressed
+ * with rle mode and the current block's sequences section is compressed
+ * with repeat mode where sequences section body size can be 1 byte.
+ */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ if (op-seqHead < 4) {
+ DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting "
+ "an uncompressed block when sequences are < 4 bytes");
+ return 0;
+ }
+#endif
+
+ *entropyWritten = 1;
+ return op - ostart;
+}
+
+/** ZSTD_compressSubBlock() :
+ * Compresses a single sub-block.
+ * @return : compressed size of the sub-block
+ * Or 0 if it failed to compress. */
+static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy,
+ const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
+ const seqDef* sequences, size_t nbSeq,
+ const BYTE* literals, size_t litSize,
+ const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
+ const ZSTD_CCtx_params* cctxParams,
+ void* dst, size_t dstCapacity,
+ const int bmi2,
+ int writeLitEntropy, int writeSeqEntropy,
+ int* litEntropyWritten, int* seqEntropyWritten,
+ U32 lastBlock)
+{
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstCapacity;
+ BYTE* op = ostart + ZSTD_blockHeaderSize;
+ DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)",
+ litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock);
+ { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable,
+ &entropyMetadata->hufMetadata, literals, litSize,
+ op, oend-op, bmi2, writeLitEntropy, litEntropyWritten);
+ FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed");
+ if (cLitSize == 0) return 0;
+ op += cLitSize;
+ }
+ { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse,
+ &entropyMetadata->fseMetadata,
+ sequences, nbSeq,
+ llCode, mlCode, ofCode,
+ cctxParams,
+ op, oend-op,
+ bmi2, writeSeqEntropy, seqEntropyWritten);
+ FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed");
+ if (cSeqSize == 0) return 0;
+ op += cSeqSize;
+ }
+ /* Write block header */
+ { size_t cSize = (op-ostart)-ZSTD_blockHeaderSize;
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
+ MEM_writeLE24(ostart, cBlockHeader24);
+ }
+ return op-ostart;
+}
+
+static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize,
+ const ZSTD_hufCTables_t* huf,
+ const ZSTD_hufCTablesMetadata_t* hufMetadata,
+ void* workspace, size_t wkspSize,
+ int writeEntropy)
+{
+ unsigned* const countWksp = (unsigned*)workspace;
+ unsigned maxSymbolValue = 255;
+ size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
+
+ if (hufMetadata->hType == set_basic) return litSize;
+ else if (hufMetadata->hType == set_rle) return 1;
+ else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) {
+ size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize);
+ if (ZSTD_isError(largest)) return litSize;
+ { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue);
+ if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize;
+ return cLitSizeEstimate + literalSectionHeaderSize;
+ } }
+ assert(0); /* impossible */
+ return 0;
+}
+
+static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
+ const BYTE* codeTable, unsigned maxCode,
+ size_t nbSeq, const FSE_CTable* fseCTable,
+ const U32* additionalBits,
+ short const* defaultNorm, U32 defaultNormLog,
+ void* workspace, size_t wkspSize)
+{
+ unsigned* const countWksp = (unsigned*)workspace;
+ const BYTE* ctp = codeTable;
+ const BYTE* const ctStart = ctp;
+ const BYTE* const ctEnd = ctStart + nbSeq;
+ size_t cSymbolTypeSizeEstimateInBits = 0;
+ unsigned max = maxCode;
+
+ HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
+ if (type == set_basic) {
+ cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max);
+ } else if (type == set_rle) {
+ cSymbolTypeSizeEstimateInBits = 0;
+ } else if (type == set_compressed || type == set_repeat) {
+ cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max);
+ }
+ if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10;
+ while (ctp < ctEnd) {
+ if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp];
+ else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */
+ ctp++;
+ }
+ return cSymbolTypeSizeEstimateInBits / 8;
+}
+
+static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
+ const BYTE* llCodeTable,
+ const BYTE* mlCodeTable,
+ size_t nbSeq,
+ const ZSTD_fseCTables_t* fseTables,
+ const ZSTD_fseCTablesMetadata_t* fseMetadata,
+ void* workspace, size_t wkspSize,
+ int writeEntropy)
+{
+ size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
+ size_t cSeqSizeEstimate = 0;
+ cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
+ nbSeq, fseTables->offcodeCTable, NULL,
+ OF_defaultNorm, OF_defaultNormLog,
+ workspace, wkspSize);
+ cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
+ nbSeq, fseTables->litlengthCTable, LL_bits,
+ LL_defaultNorm, LL_defaultNormLog,
+ workspace, wkspSize);
+ cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
+ nbSeq, fseTables->matchlengthCTable, ML_bits,
+ ML_defaultNorm, ML_defaultNormLog,
+ workspace, wkspSize);
+ if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
+ return cSeqSizeEstimate + sequencesSectionHeaderSize;
+}
+
+static size_t ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize,
+ const BYTE* ofCodeTable,
+ const BYTE* llCodeTable,
+ const BYTE* mlCodeTable,
+ size_t nbSeq,
+ const ZSTD_entropyCTables_t* entropy,
+ const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
+ void* workspace, size_t wkspSize,
+ int writeLitEntropy, int writeSeqEntropy) {
+ size_t cSizeEstimate = 0;
+ cSizeEstimate += ZSTD_estimateSubBlockSize_literal(literals, litSize,
+ &entropy->huf, &entropyMetadata->hufMetadata,
+ workspace, wkspSize, writeLitEntropy);
+ cSizeEstimate += ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
+ nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
+ workspace, wkspSize, writeSeqEntropy);
+ return cSizeEstimate + ZSTD_blockHeaderSize;
+}
+
+static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata)
+{
+ if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle)
+ return 1;
+ if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle)
+ return 1;
+ if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle)
+ return 1;
+ return 0;
+}
+
+/** ZSTD_compressSubBlock_multi() :
+ * Breaks super-block into multiple sub-blocks and compresses them.
+ * Entropy will be written to the first block.
+ * The following blocks will use repeat mode to compress.
+ * All sub-blocks are compressed blocks (no raw or rle blocks).
+ * @return : compressed size of the super block (which is multiple ZSTD blocks)
+ * Or 0 if it failed to compress. */
+static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
+ const ZSTD_compressedBlockState_t* prevCBlock,
+ ZSTD_compressedBlockState_t* nextCBlock,
+ const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
+ const ZSTD_CCtx_params* cctxParams,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const int bmi2, U32 lastBlock,
+ void* workspace, size_t wkspSize)
+{
+ const seqDef* const sstart = seqStorePtr->sequencesStart;
+ const seqDef* const send = seqStorePtr->sequences;
+ const seqDef* sp = sstart;
+ const BYTE* const lstart = seqStorePtr->litStart;
+ const BYTE* const lend = seqStorePtr->lit;
+ const BYTE* lp = lstart;
+ BYTE const* ip = (BYTE const*)src;
+ BYTE const* const iend = ip + srcSize;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstCapacity;
+ BYTE* op = ostart;
+ const BYTE* llCodePtr = seqStorePtr->llCode;
+ const BYTE* mlCodePtr = seqStorePtr->mlCode;
+ const BYTE* ofCodePtr = seqStorePtr->ofCode;
+ size_t targetCBlockSize = cctxParams->targetCBlockSize;
+ size_t litSize, seqCount;
+ int writeLitEntropy = entropyMetadata->hufMetadata.hType == set_compressed;
+ int writeSeqEntropy = 1;
+ int lastSequence = 0;
+
+ DEBUGLOG(5, "ZSTD_compressSubBlock_multi (litSize=%u, nbSeq=%u)",
+ (unsigned)(lend-lp), (unsigned)(send-sstart));
+
+ litSize = 0;
+ seqCount = 0;
+ do {
+ size_t cBlockSizeEstimate = 0;
+ if (sstart == send) {
+ lastSequence = 1;
+ } else {
+ const seqDef* const sequence = sp + seqCount;
+ lastSequence = sequence == send - 1;
+ litSize += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength;
+ seqCount++;
+ }
+ if (lastSequence) {
+ assert(lp <= lend);
+ assert(litSize <= (size_t)(lend - lp));
+ litSize = (size_t)(lend - lp);
+ }
+ /* I think there is an optimization opportunity here.
+ * Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful
+ * since it recalculates estimate from scratch.
+ * For example, it would recount literal distribution and symbol codes everytime.
+ */
+ cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount,
+ &nextCBlock->entropy, entropyMetadata,
+ workspace, wkspSize, writeLitEntropy, writeSeqEntropy);
+ if (cBlockSizeEstimate > targetCBlockSize || lastSequence) {
+ int litEntropyWritten = 0;
+ int seqEntropyWritten = 0;
+ const size_t decompressedSize = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence);
+ const size_t cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata,
+ sp, seqCount,
+ lp, litSize,
+ llCodePtr, mlCodePtr, ofCodePtr,
+ cctxParams,
+ op, oend-op,
+ bmi2, writeLitEntropy, writeSeqEntropy,
+ &litEntropyWritten, &seqEntropyWritten,
+ lastBlock && lastSequence);
+ FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed");
+ if (cSize > 0 && cSize < decompressedSize) {
+ DEBUGLOG(5, "Committed the sub-block");
+ assert(ip + decompressedSize <= iend);
+ ip += decompressedSize;
+ sp += seqCount;
+ lp += litSize;
+ op += cSize;
+ llCodePtr += seqCount;
+ mlCodePtr += seqCount;
+ ofCodePtr += seqCount;
+ litSize = 0;
+ seqCount = 0;
+ /* Entropy only needs to be written once */
+ if (litEntropyWritten) {
+ writeLitEntropy = 0;
+ }
+ if (seqEntropyWritten) {
+ writeSeqEntropy = 0;
+ }
+ }
+ }
+ } while (!lastSequence);
+ if (writeLitEntropy) {
+ DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
+ memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
+ }
+ if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
+ /* If we haven't written our entropy tables, then we've violated our contract and
+ * must emit an uncompressed block.
+ */
+ DEBUGLOG(5, "ZSTD_compressSubBlock_multi has sequence entropy tables unwritten");
+ return 0;
+ }
+ if (ip < iend) {
+ size_t const cSize = ZSTD_noCompressBlock(op, oend - op, ip, iend - ip, lastBlock);
+ DEBUGLOG(5, "ZSTD_compressSubBlock_multi last sub-block uncompressed, %zu bytes", (size_t)(iend - ip));
+ FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
+ assert(cSize != 0);
+ op += cSize;
+ /* We have to regenerate the repcodes because we've skipped some sequences */
+ if (sp < send) {
+ seqDef const* seq;
+ repcodes_t rep;
+ memcpy(&rep, prevCBlock->rep, sizeof(rep));
+ for (seq = sstart; seq < sp; ++seq) {
+ rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
+ }
+ memcpy(nextCBlock->rep, &rep, sizeof(rep));
+ }
+ }
+ DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
+ return op-ostart;
+}
+
+size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ void const* src, size_t srcSize,
+ unsigned lastBlock) {
+ ZSTD_entropyCTablesMetadata_t entropyMetadata;
+
+ FORWARD_IF_ERROR(ZSTD_buildSuperBlockEntropy(&zc->seqStore,
+ &zc->blockState.prevCBlock->entropy,
+ &zc->blockState.nextCBlock->entropy,
+ &zc->appliedParams,
+ &entropyMetadata,
+ zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
+
+ return ZSTD_compressSubBlock_multi(&zc->seqStore,
+ zc->blockState.prevCBlock,
+ zc->blockState.nextCBlock,
+ &entropyMetadata,
+ &zc->appliedParams,
+ dst, dstCapacity,
+ src, srcSize,
+ zc->bmi2, lastBlock,
+ zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
+}
diff --git a/thirdparty/zstd/compress/zstd_compress_superblock.h b/thirdparty/zstd/compress/zstd_compress_superblock.h
new file mode 100644
index 0000000000..07f4cb1dc6
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_superblock.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#ifndef ZSTD_COMPRESS_ADVANCED_H
+#define ZSTD_COMPRESS_ADVANCED_H
+
+/*-*************************************
+* Dependencies
+***************************************/
+
+#include "../zstd.h" /* ZSTD_CCtx */
+
+/*-*************************************
+* Target Compressed Block Size
+***************************************/
+
+/* ZSTD_compressSuperBlock() :
+ * Used to compress a super block when targetCBlockSize is being used.
+ * The given block will be compressed into multiple sub blocks that are around targetCBlockSize. */
+size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ void const* src, size_t srcSize,
+ unsigned lastBlock);
+
+#endif /* ZSTD_COMPRESS_ADVANCED_H */
diff --git a/thirdparty/zstd/compress/zstd_cwksp.h b/thirdparty/zstd/compress/zstd_cwksp.h
index fc9765bd3f..a25c9263b7 100644
--- a/thirdparty/zstd/compress/zstd_cwksp.h
+++ b/thirdparty/zstd/compress/zstd_cwksp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -14,7 +14,7 @@
/*-*************************************
* Dependencies
***************************************/
-#include "zstd_internal.h"
+#include "../common/zstd_internal.h"
#if defined (__cplusplus)
extern "C" {
@@ -24,16 +24,6 @@ extern "C" {
* Constants
***************************************/
-/* define "workspace is too large" as this number of times larger than needed */
-#define ZSTD_WORKSPACETOOLARGE_FACTOR 3
-
-/* when workspace is continuously too large
- * during at least this number of times,
- * context's memory usage is considered wasteful,
- * because it's sized to handle a worst case scenario which rarely happens.
- * In which case, resize it down to free some memory */
-#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
-
/* Since the workspace is effectively its own little malloc implementation /
* arena, when we run under ASAN, we should similarly insert redzones between
* each internal element of the workspace, so ASAN will catch overruns that
@@ -468,7 +458,7 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {
void* workspace = ZSTD_malloc(size, customMem);
DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size);
- RETURN_ERROR_IF(workspace == NULL, memory_allocation);
+ RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!");
ZSTD_cwksp_init(ws, workspace, size);
return 0;
}
diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c
index a661a48534..27eed66cfe 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.c
+++ b/thirdparty/zstd/compress/zstd_double_fast.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -63,10 +63,8 @@ size_t ZSTD_compressBlock_doubleFast_generic(
const BYTE* ip = istart;
const BYTE* anchor = istart;
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
- const U32 lowestValid = ms->window.dictLimit;
- const U32 maxDistance = 1U << cParams->windowLog;
/* presumes that, if there is a dictionary, it must be using Attach mode */
- const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
+ const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
const BYTE* const prefixLowest = base + prefixLowestIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - HASH_READ_SIZE;
@@ -96,7 +94,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
dictCParams->hashLog : hBitsL;
const U32 dictHBitsS = dictMode == ZSTD_dictMatchState ?
dictCParams->chainLog : hBitsS;
- const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictStart);
+ const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart));
DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_generic");
@@ -104,13 +102,15 @@ size_t ZSTD_compressBlock_doubleFast_generic(
/* if a dictionary is attached, it must be within window range */
if (dictMode == ZSTD_dictMatchState) {
- assert(lowestValid + maxDistance >= endIndex);
+ assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex);
}
/* init */
ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) {
- U32 const maxRep = (U32)(ip - prefixLowest);
+ U32 const current = (U32)(ip - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
+ U32 const maxRep = current - windowLow;
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
}
@@ -198,6 +198,9 @@ size_t ZSTD_compressBlock_doubleFast_generic(
} }
ip += ((ip-anchor) >> kSearchStrength) + 1;
+#if defined(__aarch64__)
+ PREFETCH_L1(ip+256);
+#endif
continue;
_search_next_long:
@@ -271,7 +274,7 @@ _match_stored:
U32 const repIndex2 = current2 - offset_2;
const BYTE* repMatch2 = dictMode == ZSTD_dictMatchState
&& repIndex2 < prefixLowestIndex ?
- dictBase - dictIndexDelta + repIndex2 :
+ dictBase + repIndex2 - dictIndexDelta :
base + repIndex2;
if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
diff --git a/thirdparty/zstd/compress/zstd_double_fast.h b/thirdparty/zstd/compress/zstd_double_fast.h
index 4fa31acfc0..14d944d69b 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.h
+++ b/thirdparty/zstd/compress/zstd_double_fast.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -15,7 +15,7 @@
extern "C" {
#endif
-#include "mem.h" /* U32 */
+#include "../common/mem.h" /* U32 */
#include "zstd_compress_internal.h" /* ZSTD_CCtx, size_t */
void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c
index 6dbefee6b7..85a3a7a91e 100644
--- a/thirdparty/zstd/compress/zstd_fast.c
+++ b/thirdparty/zstd/compress/zstd_fast.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -61,9 +61,7 @@ ZSTD_compressBlock_fast_generic(
const BYTE* ip1;
const BYTE* anchor = istart;
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 U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
const BYTE* const prefixStart = base + prefixStartIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - HASH_READ_SIZE;
@@ -74,12 +72,21 @@ ZSTD_compressBlock_fast_generic(
DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
ip0 += (ip0 == prefixStart);
ip1 = ip0 + 1;
- { U32 const maxRep = (U32)(ip0 - prefixStart);
+ { U32 const current = (U32)(ip0 - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
+ U32 const maxRep = current - windowLow;
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
}
/* Main Search Loop */
+#ifdef __INTEL_COMPILER
+ /* From intel 'The vector pragma indicates that the loop should be
+ * vectorized if it is legal to do so'. Can be used together with
+ * #pragma ivdep (but have opted to exclude that because intel
+ * warns against using it).*/
+ #pragma vector always
+#endif
while (ip1 < ilimit) { /* < instead of <=, because check at ip0+2 */
size_t mLength;
BYTE const* ip2 = ip0 + 2;
@@ -91,19 +98,25 @@ ZSTD_compressBlock_fast_generic(
U32 const current1 = (U32)(ip1-base);
U32 const matchIndex0 = hashTable[h0];
U32 const matchIndex1 = hashTable[h1];
- BYTE const* repMatch = ip2-offset_1;
+ BYTE const* repMatch = ip2 - offset_1;
const BYTE* match0 = base + matchIndex0;
const BYTE* match1 = base + matchIndex1;
U32 offcode;
+
+#if defined(__aarch64__)
+ PREFETCH_L1(ip0+256);
+#endif
+
hashTable[h0] = current0; /* update hash table */
hashTable[h1] = current1; /* update hash table */
assert(ip0 + 1 == ip1);
if ((offset_1 > 0) & (MEM_read32(repMatch) == MEM_read32(ip2))) {
- mLength = ip2[-1] == repMatch[-1] ? 1 : 0;
+ mLength = (ip2[-1] == repMatch[-1]) ? 1 : 0;
ip0 = ip2 - mLength;
match0 = repMatch - mLength;
+ mLength += 4;
offcode = 0;
goto _match;
}
@@ -128,19 +141,18 @@ _offset: /* Requires: ip0, match0 */
offset_2 = offset_1;
offset_1 = (U32)(ip0-match0);
offcode = offset_1 + ZSTD_REP_MOVE;
- mLength = 0;
+ mLength = 4;
/* Count the backwards match length */
while (((ip0>anchor) & (match0>prefixStart))
&& (ip0[-1] == match0[-1])) { ip0--; match0--; mLength++; } /* catch up */
_match: /* Requires: ip0, match0, offcode */
/* Count the forward length */
- mLength += ZSTD_count(ip0+mLength+4, match0+mLength+4, iend) + 4;
+ mLength += ZSTD_count(ip0+mLength, match0+mLength, iend);
ZSTD_storeSeq(seqStore, (size_t)(ip0-anchor), anchor, iend, offcode, mLength-MINMATCH);
/* match found */
ip0 += mLength;
anchor = ip0;
- ip1 = ip0 + 1;
if (ip0 <= ilimit) {
/* Fill Table */
@@ -148,19 +160,18 @@ _match: /* Requires: ip0, match0, offcode */
hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
- while ( ((ip0 <= ilimit) & (offset_2>0)) /* offset_2==0 means offset_2 is invalidated */
- && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) {
- /* store sequence */
- size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4;
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
- hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
- ip0 += rLength;
- ip1 = ip0 + 1;
- ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH);
- anchor = ip0;
- continue; /* faster when present (confirmed on gcc-8) ... (?) */
- }
- }
+ if (offset_2 > 0) { /* offset_2==0 means offset_2 is invalidated */
+ while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4;
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
+ hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
+ ip0 += rLength;
+ ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH);
+ anchor = ip0;
+ continue; /* faster when present (confirmed on gcc-8) ... (?) */
+ } } }
+ ip1 = ip0 + 1;
}
/* save reps for next block */
@@ -387,7 +398,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const ilimit = iend - 8;
U32 offset_1=rep[0], offset_2=rep[1];
- DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic");
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1);
/* switch to "regular" variant if extDict is invalidated due to maxDistance */
if (prefixStartIndex == dictStartIndex)
@@ -404,6 +415,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
hashTable[h] = current; /* update hash table */
+ DEBUGLOG(7, "offset_1 = %u , current = %u", offset_1, current);
assert(offset_1 <= current +1); /* check repIndex */
if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
diff --git a/thirdparty/zstd/compress/zstd_fast.h b/thirdparty/zstd/compress/zstd_fast.h
index b74a88c57c..cf6aaa8e67 100644
--- a/thirdparty/zstd/compress/zstd_fast.h
+++ b/thirdparty/zstd/compress/zstd_fast.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -15,7 +15,7 @@
extern "C" {
#endif
-#include "mem.h" /* U32 */
+#include "../common/mem.h" /* U32 */
#include "zstd_compress_internal.h"
void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c
index 9ad7e03b54..4cf5c88b53 100644
--- a/thirdparty/zstd/compress/zstd_lazy.c
+++ b/thirdparty/zstd/compress/zstd_lazy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -660,12 +660,16 @@ ZSTD_compressBlock_lazy_generic(
const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
prefixLowestIndex - (U32)(dictEnd - dictBase) :
0;
- const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictLowest);
+ const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
+
+ DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode);
/* init */
ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) {
- U32 const maxRep = (U32)(ip - prefixLowest);
+ U32 const current = (U32)(ip - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, ms->cParams.windowLog);
+ U32 const maxRep = current - windowLow;
if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
}
@@ -677,6 +681,12 @@ ZSTD_compressBlock_lazy_generic(
}
/* Match Loop */
+#if defined(__GNUC__) && defined(__x86_64__)
+ /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the
+ * code alignment is perturbed. To fix the instability align the loop on 32-bytes.
+ */
+ __asm__(".p2align 5");
+#endif
while (ip < ilimit) {
size_t matchLength=0;
size_t offset=0;
@@ -929,11 +939,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const BYTE* const ilimit = iend - 8;
const BYTE* const base = ms->window.base;
const U32 dictLimit = ms->window.dictLimit;
- const U32 lowestIndex = ms->window.lowLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* const dictBase = ms->window.dictBase;
const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const dictStart = dictBase + lowestIndex;
+ const BYTE* const dictStart = dictBase + ms->window.lowLimit;
+ const U32 windowLog = ms->cParams.windowLog;
typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms,
@@ -942,10 +952,18 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
U32 offset_1 = rep[0], offset_2 = rep[1];
+ DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic");
+
/* init */
ip += (ip == prefixStart);
/* Match Loop */
+#if defined(__GNUC__) && defined(__x86_64__)
+ /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the
+ * code alignment is perturbed. To fix the instability align the loop on 32-bytes.
+ */
+ __asm__(".p2align 5");
+#endif
while (ip < ilimit) {
size_t matchLength=0;
size_t offset=0;
@@ -953,10 +971,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
U32 current = (U32)(ip-base);
/* check repCode */
- { const U32 repIndex = (U32)(current+1 - offset_1);
+ { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current+1, windowLog);
+ const U32 repIndex = (U32)(current+1 - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
/* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -983,10 +1002,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
current++;
/* check repCode */
if (offset) {
+ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog);
const U32 repIndex = (U32)(current - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -1013,10 +1033,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
current++;
/* check repCode */
if (offset) {
+ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog);
const U32 repIndex = (U32)(current - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -1057,10 +1078,12 @@ _storeSequence:
/* check immediate repcode */
while (ip <= ilimit) {
- const U32 repIndex = (U32)((ip-base) - offset_2);
+ const U32 repCurrent = (U32)(ip-base);
+ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, repCurrent, windowLog);
+ const U32 repIndex = repCurrent - offset_2;
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
diff --git a/thirdparty/zstd/compress/zstd_lazy.h b/thirdparty/zstd/compress/zstd_lazy.h
index bb1763069f..581936f03b 100644
--- a/thirdparty/zstd/compress/zstd_lazy.h
+++ b/thirdparty/zstd/compress/zstd_lazy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/compress/zstd_ldm.c b/thirdparty/zstd/compress/zstd_ldm.c
index c3312ad3e3..8c47948358 100644
--- a/thirdparty/zstd/compress/zstd_ldm.c
+++ b/thirdparty/zstd/compress/zstd_ldm.c
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
*/
#include "zstd_ldm.h"
-#include "debug.h"
+#include "../common/debug.h"
#include "zstd_fast.h" /* ZSTD_fillHashTable() */
#include "zstd_double_fast.h" /* ZSTD_fillDoubleHashTable() */
@@ -223,6 +224,20 @@ static U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state,
return rollingHash;
}
+void ZSTD_ldm_fillHashTable(
+ ldmState_t* state, const BYTE* ip,
+ const BYTE* iend, ldmParams_t const* params)
+{
+ DEBUGLOG(5, "ZSTD_ldm_fillHashTable");
+ if ((size_t)(iend - ip) >= params->minMatchLength) {
+ U64 startingHash = ZSTD_rollingHash_compute(ip, params->minMatchLength);
+ ZSTD_ldm_fillLdmHashTable(
+ state, startingHash, ip, iend - params->minMatchLength, state->window.base,
+ params->hashLog - params->bucketSizeLog,
+ *params);
+ }
+}
+
/** ZSTD_ldm_limitTableUpdate() :
*
@@ -449,6 +464,8 @@ size_t ZSTD_ldm_generateSequences(
U32 const correction = ZSTD_window_correctOverflow(
&ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);
ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction);
+ /* invalidate dictionaries on overflow correction */
+ ldmState->loadedDictEnd = 0;
}
/* 2. We enforce the maximum offset allowed.
*
@@ -457,8 +474,14 @@ size_t ZSTD_ldm_generateSequences(
* TODO: * Test the chunk size.
* * Try invalidation after the sequence generation and test the
* the offset against maxDist directly.
+ *
+ * NOTE: Because of dictionaries + sequence splitting we MUST make sure
+ * that any offset used is valid at the END of the sequence, since it may
+ * be split into two sequences. This condition holds when using
+ * ZSTD_window_enforceMaxDist(), but if we move to checking offsets
+ * against maxDist directly, we'll have to carefully handle that case.
*/
- ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, NULL, NULL);
+ ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, &ldmState->loadedDictEnd, NULL);
/* 3. Generate the sequences for the chunk, and get newLeftoverSize. */
newLeftoverSize = ZSTD_ldm_generateSequences_internal(
ldmState, sequences, params, chunkStart, chunkSize);
@@ -566,14 +589,13 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
if (sequence.offset == 0)
break;
- assert(sequence.offset <= (1U << cParams->windowLog));
assert(ip + sequence.litLength + sequence.matchLength <= iend);
/* Fill tables for block compressor */
ZSTD_ldm_limitTableUpdate(ms, ip);
ZSTD_ldm_fillFastTables(ms, ip);
/* Run the block compressor */
- DEBUGLOG(5, "calling block compressor on segment of size %u", sequence.litLength);
+ DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength);
{
size_t const newLitLength =
blockCompressor(ms, seqStore, rep, ip, sequence.litLength);
diff --git a/thirdparty/zstd/compress/zstd_ldm.h b/thirdparty/zstd/compress/zstd_ldm.h
index a47846128b..229ea05a9e 100644
--- a/thirdparty/zstd/compress/zstd_ldm.h
+++ b/thirdparty/zstd/compress/zstd_ldm.h
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
*/
#ifndef ZSTD_LDM_H
@@ -15,7 +16,7 @@ extern "C" {
#endif
#include "zstd_compress_internal.h" /* ldmParams_t, U32 */
-#include "zstd.h" /* ZSTD_CCtx, size_t */
+#include "../zstd.h" /* ZSTD_CCtx, size_t */
/*-*************************************
* Long distance matching
@@ -23,6 +24,10 @@ extern "C" {
#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT
+void ZSTD_ldm_fillHashTable(
+ ldmState_t* state, const BYTE* ip,
+ const BYTE* iend, ldmParams_t const* params);
+
/**
* ZSTD_ldm_generateSequences():
*
diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c
index 2e50fca6ff..36fff050cf 100644
--- a/thirdparty/zstd/compress/zstd_opt.c
+++ b/thirdparty/zstd/compress/zstd_opt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -249,40 +249,6 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
}
}
-/* ZSTD_litLengthContribution() :
- * @return ( cost(litlength) - cost(0) )
- * this value can then be added to rawLiteralsCost()
- * 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 (int)WEIGHT(litLength, optLevel);
-
- /* dynamic statistics */
- { U32 const llCode = ZSTD_LLcode(litLength);
- 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
- return MAX(0, contribution); /* sometimes better, sometimes not ... */
-#endif
- }
-}
-
-/* ZSTD_literalsContribution() :
- * creates a fake cost for the literals part of a sequence
- * which can be compared to the ending cost of a match
- * should a new match start at this position */
-static int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLength,
- const optState_t* const optPtr,
- int optLevel)
-{
- int const contribution = (int)ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)
- + ZSTD_litLengthContribution(litLength, optPtr, optLevel);
- return contribution;
-}
-
/* ZSTD_getMatchPrice() :
* Provides the cost of the match part (offset + matchLength) of a sequence
* Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
@@ -603,7 +569,10 @@ U32 ZSTD_insertBtAndGetAllMatches (
U32 repLen = 0;
assert(current >= dictLimit);
if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < current-dictLimit) { /* equivalent to `current > repIndex >= dictLimit` */
- if (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch)) {
+ /* We must validate the repcode offset because when we're using a dictionary the
+ * valid offset range shrinks when the dictionary goes out of bounds.
+ */
+ if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
}
} else { /* repIndex < dictLimit || repIndex >= current */
@@ -799,30 +768,6 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
/*-*******************************
* Optimal parser
*********************************/
-typedef struct repcodes_s {
- U32 rep[3];
-} repcodes_t;
-
-static repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
-{
- repcodes_t newReps;
- if (offset >= ZSTD_REP_NUM) { /* full offset */
- newReps.rep[2] = rep[1];
- newReps.rep[1] = rep[0];
- newReps.rep[0] = offset - ZSTD_REP_MOVE;
- } else { /* repcode */
- U32 const repCode = offset + ll0;
- if (repCode > 0) { /* note : if repCode==0, no change */
- U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
- newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];
- newReps.rep[1] = rep[0];
- newReps.rep[0] = currentOffset;
- } else { /* repCode == 0 */
- memcpy(&newReps, rep, sizeof(newReps));
- }
- }
- return newReps;
-}
static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
@@ -839,7 +784,7 @@ listStats(const U32* table, int lastEltID)
int enb;
for (enb=0; enb < nbElts; enb++) {
(void)table;
- //RAWLOG(2, "%3i:%3i, ", enb, table[enb]);
+ /* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */
RAWLOG(2, "%4i,", table[enb]);
}
RAWLOG(2, " \n");
@@ -894,7 +839,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
{ U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
opt[0].mlen = 0; /* means is_a_literal */
opt[0].litlen = litlen;
- opt[0].price = ZSTD_literalsContribution(anchor, litlen, optStatePtr, optLevel);
+ /* We don't need to include the actual price of the literals because
+ * it is static for the duration of the forward pass, and is included
+ * in every price. We include the literal length to avoid negative
+ * prices when we subtract the previous literal length.
+ */
+ opt[0].price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
/* large match -> immediate encoding */
{ U32 const maxML = matches[nbMatches-1].len;
@@ -923,7 +873,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
U32 const offset = matches[matchNb].off;
U32 const end = matches[matchNb].len;
- repcodes_t const repHistory = ZSTD_updateRep(rep, offset, ll0);
for ( ; pos <= end ; pos++ ) {
U32 const matchPrice = ZSTD_getMatchPrice(offset, pos, optStatePtr, optLevel);
U32 const sequencePrice = literalsPrice + matchPrice;
@@ -933,8 +882,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
opt[pos].off = offset;
opt[pos].litlen = litlen;
opt[pos].price = sequencePrice;
- ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
- memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
} }
last_pos = pos-1;
}
@@ -961,7 +908,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
opt[cur].off = 0;
opt[cur].litlen = litlen;
opt[cur].price = price;
- memcpy(opt[cur].rep, opt[cur-1].rep, sizeof(opt[cur].rep));
} else {
DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)",
inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),
@@ -969,6 +915,21 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
}
}
+ /* Set the repcodes of the current position. We must do it here
+ * because we rely on the repcodes of the 2nd to last sequence being
+ * correct to set the next chunks repcodes during the backward
+ * traversal.
+ */
+ ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t));
+ assert(cur >= opt[cur].mlen);
+ if (opt[cur].mlen != 0) {
+ U32 const prev = cur - opt[cur].mlen;
+ repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
+ memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
+ } else {
+ memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
+ }
+
/* last match must start at a minimum distance of 8 from oend */
if (inr > ilimit) continue;
@@ -1009,7 +970,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
/* set prices using matches found at position == cur */
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
U32 const offset = matches[matchNb].off;
- repcodes_t const repHistory = ZSTD_updateRep(opt[cur].rep, offset, ll0);
U32 const lastML = matches[matchNb].len;
U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;
U32 mlen;
@@ -1029,8 +989,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
opt[pos].off = offset;
opt[pos].litlen = litlen;
opt[pos].price = price;
- ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
- memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
} else {
DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)",
pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
@@ -1046,6 +1004,17 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
assert(opt[0].mlen == 0);
+ /* Set the next chunk's repcodes based on the repcodes of the beginning
+ * of the last match, and the last sequence. This avoids us having to
+ * update them while traversing the sequences.
+ */
+ if (lastSequence.mlen != 0) {
+ repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
+ memcpy(rep, &reps, sizeof(reps));
+ } else {
+ memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
+ }
+
{ U32 const storeEnd = cur + 1;
U32 storeStart = storeEnd;
U32 seqPos = cur;
@@ -1082,20 +1051,6 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
continue; /* will finish */
}
- /* repcodes update : like ZSTD_updateRep(), but update in place */
- if (offCode >= ZSTD_REP_NUM) { /* full offset */
- rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = offCode - ZSTD_REP_MOVE;
- } else { /* repcode */
- U32 const repCode = offCode + (llen==0);
- if (repCode) { /* note : if repCode==0, no change */
- U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
- if (repCode >= 2) rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = currentOffset;
- } }
-
assert(anchor + llen <= iend);
ZSTD_updateStats(optStatePtr, llen, anchor, offCode, mlen);
ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen-MINMATCH);
@@ -1104,7 +1059,6 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
} }
ZSTD_setBasePrices(optStatePtr, optLevel);
}
-
} /* while (ip < ilimit) */
/* Return the last literals size */
diff --git a/thirdparty/zstd/compress/zstd_opt.h b/thirdparty/zstd/compress/zstd_opt.h
index 094f747665..9aba8a9018 100644
--- a/thirdparty/zstd/compress/zstd_opt.h
+++ b/thirdparty/zstd/compress/zstd_opt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c
index bc3062b530..1e3c8fdbee 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.c
+++ b/thirdparty/zstd/compress/zstdmt_compress.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -22,9 +22,9 @@
/* ====== Dependencies ====== */
#include <string.h> /* memcpy, memset */
#include <limits.h> /* INT_MAX, UINT_MAX */
-#include "mem.h" /* MEM_STATIC */
-#include "pool.h" /* threadpool */
-#include "threading.h" /* mutex */
+#include "../common/mem.h" /* MEM_STATIC */
+#include "../common/pool.h" /* threadpool */
+#include "../common/threading.h" /* mutex */
#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
#include "zstd_ldm.h"
#include "zstdmt_compress.h"
@@ -461,7 +461,13 @@ typedef struct {
ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
} serialState_t;
-static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool* seqPool, ZSTD_CCtx_params params, size_t jobSize)
+static int
+ZSTDMT_serialState_reset(serialState_t* serialState,
+ ZSTDMT_seqPool* seqPool,
+ ZSTD_CCtx_params params,
+ size_t jobSize,
+ const void* dict, size_t const dictSize,
+ ZSTD_dictContentType_e dictContentType)
{
/* Adjust parameters */
if (params.ldmParams.enableLdm) {
@@ -490,8 +496,7 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
/* Size the seq pool tables */
ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));
/* Reset the window */
- ZSTD_window_clear(&serialState->ldmState.window);
- serialState->ldmWindow = serialState->ldmState.window;
+ ZSTD_window_init(&serialState->ldmState.window);
/* Resize tables and output space if necessary. */
if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {
ZSTD_free(serialState->ldmState.hashTable, cMem);
@@ -506,7 +511,24 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
/* Zero the tables */
memset(serialState->ldmState.hashTable, 0, hashSize);
memset(serialState->ldmState.bucketOffsets, 0, bucketSize);
+
+ /* Update window state and fill hash table with dict */
+ serialState->ldmState.loadedDictEnd = 0;
+ if (dictSize > 0) {
+ if (dictContentType == ZSTD_dct_rawContent) {
+ BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
+ ZSTD_window_update(&serialState->ldmState.window, dict, dictSize);
+ ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, &params.ldmParams);
+ serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
+ } else {
+ /* don't even load anything */
+ }
+ }
+
+ /* Initialize serialState's copy of ldmWindow. */
+ serialState->ldmWindow = serialState->ldmState.window;
}
+
serialState->params = params;
serialState->params.jobSize = (U32)jobSize;
return 0;
@@ -1054,7 +1076,7 @@ static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(const ZSTD_CCtx_params* params)
static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
{
if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);
- FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) );
+ FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , "");
mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, nbWorkers);
if (mtctx->bufPool == NULL) return ERROR(memory_allocation);
mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);
@@ -1076,7 +1098,7 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)",
compressionLevel);
mtctx->params.compressionLevel = compressionLevel;
- { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, 0, 0);
+ { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0);
cParams.windowLog = saved_wlog;
mtctx->params.cParams = cParams;
}
@@ -1235,7 +1257,8 @@ ZSTDMT_computeNbJobs(const ZSTD_CCtx_params* params, size_t srcSize, unsigned nb
/* ZSTDMT_compress_advanced_internal() :
* This is a blocking function : it will only give back control to caller after finishing its compression job.
*/
-static size_t ZSTDMT_compress_advanced_internal(
+static size_t
+ZSTDMT_compress_advanced_internal(
ZSTDMT_CCtx* mtctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -1267,10 +1290,11 @@ static size_t ZSTDMT_compress_advanced_internal(
assert(avgJobSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) );
- if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize))
+ /* LDM doesn't even try to load the dictionary in single-ingestion mode */
+ if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize, NULL, 0, ZSTD_dct_auto))
return ERROR(memory_allocation);
- FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) ); /* only expands if necessary */
+ FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) , ""); /* only expands if necessary */
{ unsigned u;
for (u=0; u<nbJobs; u++) {
@@ -1403,7 +1427,7 @@ size_t ZSTDMT_initCStream_internal(
/* init */
if (params.nbWorkers != mtctx->params.nbWorkers)
- FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) );
+ 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 = (size_t)ZSTDMT_JOBSIZE_MAX;
@@ -1500,7 +1524,8 @@ size_t ZSTDMT_initCStream_internal(
mtctx->allJobsCompleted = 0;
mtctx->consumed = 0;
mtctx->produced = 0;
- if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize))
+ if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
+ dict, dictSize, dictContentType))
return ERROR(memory_allocation);
return 0;
}
@@ -1714,9 +1739,11 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
assert(mtctx->doneJobID < mtctx->nextJobID);
assert(cSize >= mtctx->jobs[wJobID].dstFlushed);
assert(mtctx->jobs[wJobID].dstBuff.start != NULL);
- memcpy((char*)output->dst + output->pos,
- (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
- toFlush);
+ if (toFlush > 0) {
+ memcpy((char*)output->dst + output->pos,
+ (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
+ toFlush);
+ }
output->pos += toFlush;
mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */
@@ -1786,7 +1813,7 @@ static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
BYTE const* const bufferStart = (BYTE const*)buffer.start;
BYTE const* const bufferEnd = bufferStart + buffer.capacity;
BYTE const* const rangeStart = (BYTE const*)range.start;
- BYTE const* const rangeEnd = rangeStart + range.size;
+ BYTE const* const rangeEnd = range.size != 0 ? rangeStart + range.size : rangeStart;
if (rangeStart == NULL || bufferStart == NULL)
return 0;
@@ -2060,7 +2087,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|| ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */
size_t const jobSize = mtctx->inBuff.filled;
assert(mtctx->inBuff.filled <= mtctx->targetSectionSize);
- FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) );
+ FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) , "");
}
/* check for potential compressed data ready to be flushed */
@@ -2074,7 +2101,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
{
- FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) );
+ FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) , "");
/* recommended next input size : fill current input buffer */
return mtctx->targetSectionSize - mtctx->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */
@@ -2091,7 +2118,7 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* ou
|| ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) { /* need a last 0-size block to end frame */
DEBUGLOG(5, "ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)",
(U32)srcSize, (U32)endFrame);
- FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) );
+ FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) , "");
}
/* check if there is any data available to flush */
diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h
index 12a526087d..89914eb7f8 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.h
+++ b/thirdparty/zstd/compress/zstdmt_compress.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -40,7 +40,7 @@
/* === Dependencies === */
#include <stddef.h> /* size_t */
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
-#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
+#include "../zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
/* === Constants === */
diff --git a/thirdparty/zstd/decompress/huf_decompress.c b/thirdparty/zstd/decompress/huf_decompress.c
index bb2d0a96bc..68293a1309 100644
--- a/thirdparty/zstd/decompress/huf_decompress.c
+++ b/thirdparty/zstd/decompress/huf_decompress.c
@@ -1,47 +1,27 @@
/* ******************************************************************
- huff0 huffman decoder,
- part of Finite State Entropy library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ * huff0 huffman decoder,
+ * part of Finite State Entropy library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* **************************************************************
* Dependencies
****************************************************************/
#include <string.h> /* memcpy, memset */
-#include "compiler.h"
-#include "bitstream.h" /* BIT_* */
-#include "fse.h" /* to compress headers */
+#include "../common/compiler.h"
+#include "../common/bitstream.h" /* BIT_* */
+#include "../common/fse.h" /* to compress headers */
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
-#include "error_private.h"
+#include "../common/huf.h"
+#include "../common/error_private.h"
/* **************************************************************
* Macros
@@ -61,9 +41,6 @@
* Error Management
****************************************************************/
#define HUF_isError ERR_isError
-#ifndef CHECK_F
-#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; }
-#endif
/* **************************************************************
@@ -181,17 +158,29 @@ size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize
/* fill DTable */
{ U32 n;
- for (n=0; n<nbSymbols; n++) {
- U32 const w = huffWeight[n];
- U32 const length = (1 << w) >> 1;
- U32 u;
+ size_t const nEnd = nbSymbols;
+ for (n=0; n<nEnd; n++) {
+ size_t const w = huffWeight[n];
+ size_t const length = (1 << w) >> 1;
+ size_t const uStart = rankVal[w];
+ size_t const uEnd = uStart + length;
+ size_t u;
HUF_DEltX1 D;
- D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
- for (u = rankVal[w]; u < rankVal[w] + length; u++)
- dt[u] = D;
- rankVal[w] += length;
- } }
-
+ D.byte = (BYTE)n;
+ D.nbBits = (BYTE)(tableLog + 1 - w);
+ rankVal[w] = (U32)uEnd;
+ if (length < 4) {
+ /* Use length in the loop bound so the compiler knows it is short. */
+ for (u = 0; u < length; ++u)
+ dt[uStart + u] = D;
+ } else {
+ /* Unroll the loop 4 times, we know it is a power of 2. */
+ for (u = uStart; u < uEnd; u += 4) {
+ dt[u + 0] = D;
+ dt[u + 1] = D;
+ dt[u + 2] = D;
+ dt[u + 3] = D;
+ } } } }
return iSize;
}
@@ -282,6 +271,7 @@ HUF_decompress4X1_usingDTable_internal_body(
{ const BYTE* const istart = (const BYTE*) cSrc;
BYTE* const ostart = (BYTE*) dst;
BYTE* const oend = ostart + dstSize;
+ BYTE* const olimit = oend - 3;
const void* const dtPtr = DTable + 1;
const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
@@ -306,9 +296,9 @@ HUF_decompress4X1_usingDTable_internal_body(
BYTE* op2 = opStart2;
BYTE* op3 = opStart3;
BYTE* op4 = opStart4;
- U32 endSignal = BIT_DStream_unfinished;
DTableDesc const dtd = HUF_getDTableDesc(DTable);
U32 const dtLog = dtd.tableLog;
+ U32 endSignal = 1;
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
@@ -317,8 +307,7 @@ HUF_decompress4X1_usingDTable_internal_body(
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
/* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
- endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
- while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) {
+ for ( ; (endSignal) & (op4 < olimit) ; ) {
HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
@@ -335,10 +324,10 @@ HUF_decompress4X1_usingDTable_internal_body(
HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
- BIT_reloadDStream(&bitD1);
- BIT_reloadDStream(&bitD2);
- BIT_reloadDStream(&bitD3);
- BIT_reloadDStream(&bitD4);
+ endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
}
/* check corruption */
@@ -757,7 +746,6 @@ HUF_decompress1X2_usingDTable_internal_body(
return dstSize;
}
-
FORCE_INLINE_TEMPLATE size_t
HUF_decompress4X2_usingDTable_internal_body(
void* dst, size_t dstSize,
@@ -769,6 +757,7 @@ HUF_decompress4X2_usingDTable_internal_body(
{ const BYTE* const istart = (const BYTE*) cSrc;
BYTE* const ostart = (BYTE*) dst;
BYTE* const oend = ostart + dstSize;
+ BYTE* const olimit = oend - (sizeof(size_t)-1);
const void* const dtPtr = DTable+1;
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
@@ -793,7 +782,7 @@ HUF_decompress4X2_usingDTable_internal_body(
BYTE* op2 = opStart2;
BYTE* op3 = opStart3;
BYTE* op4 = opStart4;
- U32 endSignal;
+ U32 endSignal = 1;
DTableDesc const dtd = HUF_getDTableDesc(DTable);
U32 const dtLog = dtd.tableLog;
@@ -804,8 +793,29 @@ HUF_decompress4X2_usingDTable_internal_body(
CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
/* 16-32 symbols per loop (4-8 symbols per stream) */
- endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
- for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
+ for ( ; (endSignal) & (op4 < olimit); ) {
+#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
+ endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
+ endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
+ endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
+#else
HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
@@ -822,8 +832,12 @@ HUF_decompress4X2_usingDTable_internal_body(
HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
-
- endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
+ endSignal = (U32)LIKELY(
+ (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
+ & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
+#endif
}
/* check corruption */
diff --git a/thirdparty/zstd/decompress/zstd_ddict.c b/thirdparty/zstd/decompress/zstd_ddict.c
index 0af3d23bfe..c8cb8ecc95 100644
--- a/thirdparty/zstd/decompress/zstd_ddict.c
+++ b/thirdparty/zstd/decompress/zstd_ddict.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -15,17 +15,17 @@
* Dependencies
*********************************************************/
#include <string.h> /* memcpy, memmove, memset */
-#include "cpu.h" /* bmi2 */
-#include "mem.h" /* low level memory routines */
+#include "../common/cpu.h" /* bmi2 */
+#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
-#include "fse.h"
+#include "../common/fse.h"
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
+#include "../common/huf.h"
#include "zstd_decompress_internal.h"
#include "zstd_ddict.h"
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
-# include "zstd_legacy.h"
+# include "../legacy/zstd_legacy.h"
#endif
@@ -65,6 +65,10 @@ void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
dctx->virtualStart = ddict->dictContent;
dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
dctx->previousDstEnd = dctx->dictEnd;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ dctx->dictContentBeginForFuzzing = dctx->prefixStart;
+ dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
+#endif
if (ddict->entropyPresent) {
dctx->litEntropy = 1;
dctx->fseEntropy = 1;
@@ -107,7 +111,7 @@ ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict,
/* load entropy tables */
RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy(
&ddict->entropy, ddict->dictContent, ddict->dictSize)),
- dictionary_corrupted);
+ dictionary_corrupted, "");
ddict->entropyPresent = 1;
return 0;
}
@@ -133,7 +137,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
/* parse dictionary content */
- FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) );
+ FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , "");
return 0;
}
diff --git a/thirdparty/zstd/decompress/zstd_ddict.h b/thirdparty/zstd/decompress/zstd_ddict.h
index 0479d11bb0..af307efd3d 100644
--- a/thirdparty/zstd/decompress/zstd_ddict.h
+++ b/thirdparty/zstd/decompress/zstd_ddict.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -16,7 +16,7 @@
* Dependencies
*********************************************************/
#include <stddef.h> /* size_t */
-#include "zstd.h" /* ZSTD_DDict, and several public functions */
+#include "../zstd.h" /* ZSTD_DDict, and several public functions */
/*-*******************************************************
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
index dd4591b7be..be5c7cfc33 100644
--- a/thirdparty/zstd/decompress/zstd_decompress.c
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -56,19 +56,19 @@
* Dependencies
*********************************************************/
#include <string.h> /* memcpy, memmove, memset */
-#include "cpu.h" /* bmi2 */
-#include "mem.h" /* low level memory routines */
+#include "../common/cpu.h" /* bmi2 */
+#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
-#include "fse.h"
+#include "../common/fse.h"
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
-#include "zstd_internal.h" /* blockProperties_t */
+#include "../common/huf.h"
+#include "../common/zstd_internal.h" /* blockProperties_t */
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
-# include "zstd_legacy.h"
+# include "../legacy/zstd_legacy.h"
#endif
@@ -111,7 +111,12 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
dctx->legacyContext = NULL;
dctx->previousLegacyVersion = 0;
dctx->noForwardProgress = 0;
+ dctx->oversizedDuration = 0;
dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
+ dctx->outBufferMode = ZSTD_obm_buffered;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ dctx->dictContentEndForFuzzing = NULL;
+#endif
}
ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
@@ -208,7 +213,7 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
{
size_t const minInputSize = ZSTD_startingInputLength(format);
- RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, "");
{ BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
U32 const dictID= fhd & 3;
@@ -256,7 +261,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
zfhPtr->frameType = ZSTD_skippableFrame;
return 0;
}
- RETURN_ERROR(prefix_unknown);
+ RETURN_ERROR(prefix_unknown, "");
}
/* ensure there is enough `srcSize` to fully read/decode frame header */
@@ -280,7 +285,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
if (!singleSegment) {
BYTE const wlByte = ip[pos++];
U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
- RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge);
+ RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, "");
windowSize = (1ULL << windowLog);
windowSize += (windowSize >> 3) * (wlByte&7);
}
@@ -352,14 +357,14 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
U32 sizeU32;
- RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
- frameParameter_unsupported);
+ frameParameter_unsupported, "");
{
size_t const skippableSize = skippableHeaderSize + sizeU32;
- RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong);
+ RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
return skippableSize;
}
}
@@ -439,7 +444,7 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he
* harder.
*/
RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
- dictionary_wrong);
+ dictionary_wrong, "");
#endif
if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
return 0;
@@ -559,17 +564,6 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
* Frame decoding
***************************************************************/
-
-void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
-{
- if (dst != dctx->previousDstEnd) { /* not contiguous */
- dctx->dictEnd = dctx->previousDstEnd;
- dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
- dctx->prefixStart = dst;
- dctx->previousDstEnd = dst;
- }
-}
-
/** ZSTD_insertBlock() :
* insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
@@ -587,9 +581,9 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
DEBUGLOG(5, "ZSTD_copyRawBlock");
if (dst == NULL) {
if (srcSize == 0) return 0;
- RETURN_ERROR(dstBuffer_null);
+ RETURN_ERROR(dstBuffer_null, "");
}
- RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall);
+ RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
memcpy(dst, src, srcSize);
return srcSize;
}
@@ -600,9 +594,9 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
{
if (dst == NULL) {
if (regenSize == 0) return 0;
- RETURN_ERROR(dstBuffer_null);
+ RETURN_ERROR(dstBuffer_null, "");
}
- RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall);
+ RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
memset(dst, b, regenSize);
return regenSize;
}
@@ -618,7 +612,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
{
const BYTE* ip = (const BYTE*)(*srcPtr);
BYTE* const ostart = (BYTE* const)dst;
- BYTE* const oend = ostart + dstCapacity;
+ BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart;
BYTE* op = ostart;
size_t remainingSrcSize = *srcSizePtr;
@@ -627,15 +621,15 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
/* check */
RETURN_ERROR_IF(
remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize,
- srcSize_wrong);
+ srcSize_wrong, "");
/* Frame Header */
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal(
ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format);
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
- srcSize_wrong);
- FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) );
+ srcSize_wrong, "");
+ FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , "");
ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
}
@@ -648,7 +642,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
ip += ZSTD_blockHeaderSize;
remainingSrcSize -= ZSTD_blockHeaderSize;
- RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong);
+ RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
switch(blockProperties.blockType)
{
@@ -663,13 +657,15 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
break;
case bt_reserved :
default:
- RETURN_ERROR(corruption_detected);
+ RETURN_ERROR(corruption_detected, "invalid block type");
}
if (ZSTD_isError(decodedSize)) return decodedSize;
if (dctx->fParams.checksumFlag)
XXH64_update(&dctx->xxhState, op, decodedSize);
- op += decodedSize;
+ if (decodedSize != 0)
+ op += decodedSize;
+ assert(ip != NULL);
ip += cBlockSize;
remainingSrcSize -= cBlockSize;
if (blockProperties.lastBlock) break;
@@ -677,14 +673,14 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
- corruption_detected);
+ corruption_detected, "");
}
if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
U32 checkRead;
- RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong);
+ RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, "");
checkRead = MEM_readLE32(ip);
- RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong);
+ RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
ip += 4;
remainingSrcSize -= 4;
}
@@ -741,7 +737,7 @@ 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);
- FORWARD_IF_ERROR(skippableSize);
+ FORWARD_IF_ERROR(skippableSize, "readSkippableFrameSize failed");
assert(skippableSize <= srcSize);
src = (const BYTE *)src + skippableSize;
@@ -751,11 +747,11 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
if (ddict) {
/* we were called from ZSTD_decompress_usingDDict */
- FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict));
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), "");
} else {
/* this will initialize correctly with no dict if dict == NULL, so
* use this in all cases but ddict */
- FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), "");
}
ZSTD_checkContinuity(dctx, dst);
@@ -776,7 +772,8 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
"error.");
if (ZSTD_isError(res)) return res;
assert(res <= dstCapacity);
- dst = (BYTE*)dst + res;
+ if (res != 0)
+ dst = (BYTE*)dst + res;
dstCapacity -= res;
}
moreThan1Frame = 1;
@@ -824,7 +821,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
size_t regenSize;
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
- RETURN_ERROR_IF(dctx==NULL, memory_allocation);
+ RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!");
regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
ZSTD_freeDCtx(dctx);
return regenSize;
@@ -842,6 +839,24 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
****************************************/
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
+/**
+ * Similar to ZSTD_nextSrcSizeToDecompress(), but when when a block input can be streamed,
+ * we allow taking a partial block as the input. Currently only raw uncompressed blocks can
+ * be streamed.
+ *
+ * For blocks that can be streamed, this allows us to reduce the latency until we produce
+ * output, and avoid copying the input.
+ *
+ * @param inputSize - The total amount of input that the caller currently has.
+ */
+static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) {
+ if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock))
+ return dctx->expected;
+ if (dctx->bType != bt_raw)
+ return dctx->expected;
+ return MIN(MAX(inputSize, 1), dctx->expected);
+}
+
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
switch(dctx->stage)
{
@@ -874,7 +889,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
{
DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
/* Sanity check */
- RETURN_ERROR_IF(srcSize != dctx->expected, srcSize_wrong, "not allowed");
+ RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed");
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
switch (dctx->stage)
@@ -899,7 +914,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
case ZSTDds_decodeFrameHeader:
assert(src != NULL);
memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
- FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
+ FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), "");
dctx->expected = ZSTD_blockHeaderSize;
dctx->stage = ZSTDds_decodeBlockHeader;
return 0;
@@ -941,29 +956,41 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
case bt_compressed:
DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);
+ dctx->expected = 0; /* Streaming not supported */
break;
case bt_raw :
+ assert(srcSize <= dctx->expected);
rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
+ FORWARD_IF_ERROR(rSize, "ZSTD_copyRawBlock failed");
+ assert(rSize == srcSize);
+ dctx->expected -= rSize;
break;
case bt_rle :
rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);
+ dctx->expected = 0; /* Streaming not supported */
break;
case bt_reserved : /* should never happen */
default:
- RETURN_ERROR(corruption_detected);
+ RETURN_ERROR(corruption_detected, "invalid block type");
}
- if (ZSTD_isError(rSize)) return rSize;
+ FORWARD_IF_ERROR(rSize, "");
RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
dctx->decodedSize += rSize;
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
+ dctx->previousDstEnd = (char*)dst + rSize;
+
+ /* Stay on the same stage until we are finished streaming the block. */
+ if (dctx->expected > 0) {
+ return rSize;
+ }
if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
RETURN_ERROR_IF(
dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
&& dctx->decodedSize != dctx->fParams.frameContentSize,
- corruption_detected);
+ corruption_detected, "");
if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
dctx->expected = 4;
dctx->stage = ZSTDds_checkChecksum;
@@ -974,7 +1001,6 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
} else {
dctx->stage = ZSTDds_decodeBlockHeader;
dctx->expected = ZSTD_blockHeaderSize;
- dctx->previousDstEnd = (char*)dst + rSize;
}
return rSize;
}
@@ -984,7 +1010,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
{ U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
U32 const check32 = MEM_readLE32(src);
DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
- RETURN_ERROR_IF(check32 != h32, checksum_wrong);
+ RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
dctx->expected = 0;
dctx->stage = ZSTDds_getFrameHeaderSize;
return 0;
@@ -1005,7 +1031,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
default:
assert(0); /* impossible */
- RETURN_ERROR(GENERIC); /* some compiler require default to do something */
+ RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
}
}
@@ -1016,6 +1042,10 @@ static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dict
dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
dctx->prefixStart = dict;
dctx->previousDstEnd = (const char*)dict + dictSize;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ dctx->dictContentBeginForFuzzing = dctx->prefixStart;
+ dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
+#endif
return 0;
}
@@ -1029,7 +1059,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
const BYTE* dictPtr = (const BYTE*)dict;
const BYTE* const dictEnd = dictPtr + dictSize;
- RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted);
+ RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small");
assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */
dictPtr += 8; /* skip header = magic + dictID */
@@ -1048,16 +1078,16 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
dictPtr, dictEnd - dictPtr,
workspace, workspaceSize);
#endif
- RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted);
+ RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
dictPtr += hSize;
}
{ short offcodeNCount[MaxOff+1];
unsigned offcodeMaxValue = MaxOff, offcodeLog;
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted);
- RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
+ RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, "");
+ RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->OFTable,
offcodeNCount, offcodeMaxValue,
OF_base, OF_bits,
@@ -1068,9 +1098,9 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
{ short matchlengthNCount[MaxML+1];
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted);
- RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
+ RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, "");
+ RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->MLTable,
matchlengthNCount, matchlengthMaxValue,
ML_base, ML_bits,
@@ -1081,9 +1111,9 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
{ short litlengthNCount[MaxLL+1];
unsigned litlengthMaxValue = MaxLL, litlengthLog;
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
- RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
- RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted);
- RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
+ RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
+ RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, "");
+ RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->LLTable,
litlengthNCount, litlengthMaxValue,
LL_base, LL_bits,
@@ -1091,13 +1121,13 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
dictPtr += litlengthHeaderSize;
}
- RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
+ RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
{ int i;
size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
for (i=0; i<3; i++) {
U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
RETURN_ERROR_IF(rep==0 || rep > dictContentSize,
- dictionary_corrupted);
+ dictionary_corrupted, "");
entropy->rep[i] = rep;
} }
@@ -1115,7 +1145,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
/* load entropy tables */
{ size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
- RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted);
+ RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, "");
dict = (const char*)dict + eSize;
dictSize -= eSize;
}
@@ -1138,6 +1168,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
dctx->litEntropy = dctx->fseEntropy = 0;
dctx->dictID = 0;
+ dctx->bType = bt_reserved;
ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
dctx->LLTptr = dctx->entropy.LLTable;
@@ -1149,11 +1180,11 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
{
- FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
+ FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
if (dict && dictSize)
RETURN_ERROR_IF(
ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
- dictionary_corrupted);
+ dictionary_corrupted, "");
return 0;
}
@@ -1172,7 +1203,7 @@ size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
DEBUGLOG(4, "DDict is %s",
dctx->ddictIsCold ? "~cold~" : "hot!");
}
- FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
+ FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
if (ddict) { /* NULL ddict is equivalent to no dictionary */
ZSTD_copyDDictParameters(dctx, ddict);
}
@@ -1263,11 +1294,11 @@ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType)
{
- RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
ZSTD_clearDict(dctx);
if (dict && dictSize != 0) {
dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
- RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation);
+ RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation, "NULL pointer!");
dctx->ddict = dctx->ddictLocal;
dctx->dictUses = ZSTD_use_indefinitely;
}
@@ -1286,7 +1317,7 @@ size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSi
size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
{
- FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType));
+ FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType), "");
dctx->dictUses = ZSTD_use_once;
return 0;
}
@@ -1303,8 +1334,8 @@ size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSiz
size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
{
DEBUGLOG(4, "ZSTD_initDStream_usingDict");
- FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );
+ FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) , "");
return ZSTD_startingInputLength(zds->format);
}
@@ -1320,8 +1351,8 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
* this function cannot fail */
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
{
- FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) );
- FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) );
+ FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
+ FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
return ZSTD_startingInputLength(dctx->format);
}
@@ -1330,14 +1361,14 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
* this function cannot fail */
size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
{
- FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only));
+ FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
return ZSTD_startingInputLength(dctx->format);
}
size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
{
- RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
ZSTD_clearDict(dctx);
if (ddict) {
dctx->ddict = ddict;
@@ -1354,9 +1385,9 @@ size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
size_t const min = (size_t)1 << bounds.lowerBound;
size_t const max = (size_t)1 << bounds.upperBound;
- RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
- RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound);
- RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound);
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
+ RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound, "");
+ RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound, "");
dctx->maxWindowSize = maxWindowSize;
return 0;
}
@@ -1379,6 +1410,10 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
bounds.upperBound = (int)ZSTD_f_zstd1_magicless;
ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
return bounds;
+ case ZSTD_d_stableOutBuffer:
+ bounds.lowerBound = (int)ZSTD_obm_buffered;
+ bounds.upperBound = (int)ZSTD_obm_stable;
+ return bounds;
default:;
}
bounds.error = ERROR(parameter_unsupported);
@@ -1398,12 +1433,12 @@ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
}
#define CHECK_DBOUNDS(p,v) { \
- RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound); \
+ RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \
}
size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
{
- RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
switch(dParam) {
case ZSTD_d_windowLogMax:
if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
@@ -1414,9 +1449,13 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
CHECK_DBOUNDS(ZSTD_d_format, value);
dctx->format = (ZSTD_format_e)value;
return 0;
+ case ZSTD_d_stableOutBuffer:
+ CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
+ dctx->outBufferMode = (ZSTD_outBufferMode_e)value;
+ return 0;
default:;
}
- RETURN_ERROR(parameter_unsupported);
+ RETURN_ERROR(parameter_unsupported, "");
}
size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
@@ -1428,7 +1467,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
}
if ( (reset == ZSTD_reset_parameters)
|| (reset == ZSTD_reset_session_and_parameters) ) {
- RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
ZSTD_clearDict(dctx);
dctx->format = ZSTD_f_zstd1;
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
@@ -1449,7 +1488,7 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
size_t const minRBSize = (size_t) neededSize;
RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
- frameParameter_windowTooLarge);
+ frameParameter_windowTooLarge, "");
return minRBSize;
}
@@ -1467,30 +1506,94 @@ size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
ZSTD_frameHeader zfh;
size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
if (ZSTD_isError(err)) return err;
- RETURN_ERROR_IF(err>0, srcSize_wrong);
+ RETURN_ERROR_IF(err>0, srcSize_wrong, "");
RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
- frameParameter_windowTooLarge);
+ frameParameter_windowTooLarge, "");
return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
}
/* ***** Decompression ***** */
-MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
{
- size_t const length = MIN(dstCapacity, srcSize);
- memcpy(dst, src, length);
- return length;
+ return (zds->inBuffSize + zds->outBuffSize) >= (neededInBuffSize + neededOutBuffSize) * ZSTD_WORKSPACETOOLARGE_FACTOR;
+}
+
+static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
+{
+ if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize))
+ zds->oversizedDuration++;
+ else
+ zds->oversizedDuration = 0;
+}
+
+static int ZSTD_DCtx_isOversizedTooLong(ZSTD_DStream* zds)
+{
+ return zds->oversizedDuration >= ZSTD_WORKSPACETOOLARGE_MAXDURATION;
+}
+
+/* Checks that the output buffer hasn't changed if ZSTD_obm_stable is used. */
+static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* output)
+{
+ ZSTD_outBuffer const expect = zds->expectedOutBuffer;
+ /* No requirement when ZSTD_obm_stable is not enabled. */
+ if (zds->outBufferMode != ZSTD_obm_stable)
+ return 0;
+ /* Any buffer is allowed in zdss_init, this must be the same for every other call until
+ * the context is reset.
+ */
+ if (zds->streamStage == zdss_init)
+ return 0;
+ /* The buffer must match our expectation exactly. */
+ if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
+ return 0;
+ RETURN_ERROR(dstBuffer_wrong, "ZSTD_obm_stable enabled but output differs!");
}
+/* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
+ * and updates the stage and the output buffer state. This call is extracted so it can be
+ * used both when reading directly from the ZSTD_inBuffer, and in buffered input mode.
+ * NOTE: You must break after calling this function since the streamStage is modified.
+ */
+static size_t ZSTD_decompressContinueStream(
+ ZSTD_DStream* zds, char** op, char* oend,
+ void const* src, size_t srcSize) {
+ int const isSkipFrame = ZSTD_isSkipFrame(zds);
+ if (zds->outBufferMode == ZSTD_obm_buffered) {
+ size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
+ size_t const decodedSize = ZSTD_decompressContinue(zds,
+ zds->outBuff + zds->outStart, dstSize, src, srcSize);
+ FORWARD_IF_ERROR(decodedSize, "");
+ if (!decodedSize && !isSkipFrame) {
+ zds->streamStage = zdss_read;
+ } else {
+ zds->outEnd = zds->outStart + decodedSize;
+ zds->streamStage = zdss_flush;
+ }
+ } else {
+ /* Write directly into the output buffer */
+ size_t const dstSize = isSkipFrame ? 0 : oend - *op;
+ size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize);
+ FORWARD_IF_ERROR(decodedSize, "");
+ *op += decodedSize;
+ /* Flushing is not needed. */
+ zds->streamStage = zdss_read;
+ assert(*op <= oend);
+ assert(zds->outBufferMode == ZSTD_obm_stable);
+ }
+ return 0;
+}
size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
{
- const char* const istart = (const char*)(input->src) + input->pos;
- const char* const iend = (const char*)(input->src) + input->size;
+ const char* const src = (const char*)input->src;
+ const char* const istart = input->pos != 0 ? src + input->pos : src;
+ const char* const iend = input->size != 0 ? src + input->size : src;
const char* ip = istart;
- char* const ostart = (char*)(output->dst) + output->pos;
- char* const oend = (char*)(output->dst) + output->size;
+ char* const dst = (char*)output->dst;
+ char* const ostart = output->pos != 0 ? dst + output->pos : dst;
+ char* const oend = output->size != 0 ? dst + output->size : dst;
char* op = ostart;
U32 someMoreWork = 1;
@@ -1506,6 +1609,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
"forbidden. out: pos: %u vs size: %u",
(U32)output->pos, (U32)output->size);
DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
+ FORWARD_IF_ERROR(ZSTD_checkOutBuffer(zds, output), "");
while (someMoreWork) {
switch(zds->streamStage)
@@ -1516,6 +1620,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
zds->legacyVersion = 0;
zds->hostageByte = 0;
+ zds->expectedOutBuffer = *output;
/* fall-through */
case zdss_loadHeader :
@@ -1543,7 +1648,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
"legacy support is incompatible with static dctx");
FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
zds->previousLegacyVersion, legacyVersion,
- dict, dictSize));
+ dict, dictSize), "");
zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
{ size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */
@@ -1570,7 +1675,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
} }
/* check for single-pass mode opportunity */
- if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
+ if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
+ && zds->fParams.frameType != ZSTD_skippableFrame
&& (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
if (cSize <= (size_t)(iend-istart)) {
@@ -1586,15 +1692,23 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
break;
} }
+ /* Check output buffer is large enough for ZSTD_odm_stable. */
+ if (zds->outBufferMode == ZSTD_obm_stable
+ && zds->fParams.frameType != ZSTD_skippableFrame
+ && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
+ && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
+ RETURN_ERROR(dstSize_tooSmall, "ZSTD_obm_stable passed but ZSTD_outBuffer is too small");
+ }
+
/* Consume header (see ZSTDds_decodeFrameHeader) */
DEBUGLOG(4, "Consume header");
- FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)));
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
zds->stage = ZSTDds_skipFrame;
} else {
- FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
+ FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize), "");
zds->expected = ZSTD_blockHeaderSize;
zds->stage = ZSTDds_decodeBlockHeader;
}
@@ -1605,40 +1719,48 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
(U32)(zds->maxWindowSize >> 10) );
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
- frameParameter_windowTooLarge);
+ frameParameter_windowTooLarge, "");
/* Adapt buffer sizes to frame header instructions */
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
- size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize);
- if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) {
- size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
- DEBUGLOG(4, "inBuff : from %u to %u",
- (U32)zds->inBuffSize, (U32)neededInBuffSize);
- DEBUGLOG(4, "outBuff : from %u to %u",
- (U32)zds->outBuffSize, (U32)neededOutBuffSize);
- if (zds->staticSize) { /* static DCtx */
- DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
- assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
- RETURN_ERROR_IF(
- bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
- memory_allocation);
- } else {
- ZSTD_free(zds->inBuff, zds->customMem);
- zds->inBuffSize = 0;
- zds->outBuffSize = 0;
- zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
- RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation);
- }
- zds->inBuffSize = neededInBuffSize;
- zds->outBuff = zds->inBuff + zds->inBuffSize;
- zds->outBuffSize = neededOutBuffSize;
- } }
+ size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_obm_buffered
+ ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
+ : 0;
+
+ ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
+
+ { int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize);
+ int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds);
+
+ if (tooSmall || tooLarge) {
+ size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
+ DEBUGLOG(4, "inBuff : from %u to %u",
+ (U32)zds->inBuffSize, (U32)neededInBuffSize);
+ DEBUGLOG(4, "outBuff : from %u to %u",
+ (U32)zds->outBuffSize, (U32)neededOutBuffSize);
+ if (zds->staticSize) { /* static DCtx */
+ DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
+ assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
+ RETURN_ERROR_IF(
+ bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
+ memory_allocation, "");
+ } else {
+ ZSTD_free(zds->inBuff, zds->customMem);
+ zds->inBuffSize = 0;
+ zds->outBuffSize = 0;
+ zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
+ RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, "");
+ }
+ zds->inBuffSize = neededInBuffSize;
+ zds->outBuff = zds->inBuff + zds->inBuffSize;
+ zds->outBuffSize = neededOutBuffSize;
+ } } }
zds->streamStage = zdss_read;
/* fall-through */
case zdss_read:
DEBUGLOG(5, "stage zdss_read");
- { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip);
DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
if (neededInSize==0) { /* end of frame */
zds->streamStage = zdss_init;
@@ -1646,15 +1768,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
break;
}
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
- int const isSkipFrame = ZSTD_isSkipFrame(zds);
- size_t const decodedSize = ZSTD_decompressContinue(zds,
- zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
- ip, neededInSize);
- if (ZSTD_isError(decodedSize)) return decodedSize;
+ FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
ip += neededInSize;
- if (!decodedSize && !isSkipFrame) break; /* this was just a header */
- zds->outEnd = zds->outStart + decodedSize;
- zds->streamStage = zdss_flush;
+ /* Function modifies the stage so we must break */
break;
} }
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
@@ -1666,6 +1782,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
size_t const toLoad = neededInSize - zds->inPos;
int const isSkipFrame = ZSTD_isSkipFrame(zds);
size_t loadedSize;
+ /* At this point we shouldn't be decompressing a block that we can stream. */
+ assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip));
if (isSkipFrame) {
loadedSize = MIN(toLoad, (size_t)(iend-ip));
} else {
@@ -1679,17 +1797,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
/* decode loaded input */
- { size_t const decodedSize = ZSTD_decompressContinue(zds,
- zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
- zds->inBuff, neededInSize);
- if (ZSTD_isError(decodedSize)) return decodedSize;
- zds->inPos = 0; /* input is consumed */
- if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; } /* this was just a header */
- zds->outEnd = zds->outStart + decodedSize;
- } }
- zds->streamStage = zdss_flush;
- /* fall-through */
-
+ zds->inPos = 0; /* input is consumed */
+ FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, zds->inBuff, neededInSize), "");
+ /* Function modifies the stage so we must break */
+ break;
+ }
case zdss_flush:
{ size_t const toFlushSize = zds->outEnd - zds->outStart;
size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
@@ -1712,17 +1824,21 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
default:
assert(0); /* impossible */
- RETURN_ERROR(GENERIC); /* some compiler require default to do something */
+ RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
} }
/* result */
input->pos = (size_t)(ip - (const char*)(input->src));
output->pos = (size_t)(op - (char*)(output->dst));
+
+ /* Update the expected output buffer for ZSTD_obm_stable. */
+ zds->expectedOutBuffer = *output;
+
if ((ip==istart) && (op==ostart)) { /* no forward progress */
zds->noForwardProgress ++;
if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
- RETURN_ERROR_IF(op==oend, dstSize_tooSmall);
- RETURN_ERROR_IF(ip==iend, srcSize_wrong);
+ RETURN_ERROR_IF(op==oend, dstSize_tooSmall, "");
+ RETURN_ERROR_IF(ip==iend, srcSize_wrong, "");
assert(0);
}
} else {
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c
index 767e5f9a0b..ad3b3d8dbd 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.c
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -15,14 +15,14 @@
* Dependencies
*********************************************************/
#include <string.h> /* memcpy, memmove, memset */
-#include "compiler.h" /* prefetch */
-#include "cpu.h" /* bmi2 */
-#include "mem.h" /* low level memory routines */
+#include "../common/compiler.h" /* prefetch */
+#include "../common/cpu.h" /* bmi2 */
+#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
-#include "fse.h"
+#include "../common/fse.h"
#define HUF_STATIC_LINKING_ONLY
-#include "huf.h"
-#include "zstd_internal.h"
+#include "../common/huf.h"
+#include "../common/zstd_internal.h"
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
#include "zstd_decompress_block.h"
@@ -56,7 +56,7 @@ static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
blockProperties_t* bpPtr)
{
- RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, "");
{ U32 const cBlockHeader = MEM_readLE24(src);
U32 const cSize = cBlockHeader >> 3;
@@ -64,7 +64,7 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
bpPtr->origSize = cSize; /* only useful for RLE */
if (bpPtr->blockType == bt_rle) return 1;
- RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected);
+ RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, "");
return cSize;
}
}
@@ -80,7 +80,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
{
DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");
- RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected);
+ RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
{ const BYTE* const istart = (const BYTE*) src;
symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
@@ -89,7 +89,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
{
case set_repeat:
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
- RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted);
+ RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
/* fall-through */
case set_compressed:
@@ -121,8 +121,8 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);
break;
}
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected);
- RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected);
+ RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
+ RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
/* prefetch huffman table if cold */
if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {
@@ -160,7 +160,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
}
}
- RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected);
+ RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
@@ -190,7 +190,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
}
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
- RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected);
+ RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");
memcpy(dctx->litBuffer, istart+lhSize, litSize);
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
@@ -222,7 +222,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4");
break;
}
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected);
+ RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
@@ -440,8 +440,8 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
switch(type)
{
case set_rle :
- RETURN_ERROR_IF(!srcSize, srcSize_wrong);
- RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected);
+ RETURN_ERROR_IF(!srcSize, srcSize_wrong, "");
+ RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected, "");
{ U32 const symbol = *(const BYTE*)src;
U32 const baseline = baseValue[symbol];
U32 const nbBits = nbAdditionalBits[symbol];
@@ -453,7 +453,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
*DTablePtr = defaultTable;
return 0;
case set_repeat:
- RETURN_ERROR_IF(!flagRepeatTable, corruption_detected);
+ RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, "");
/* prefetch FSE table if used */
if (ddictIsCold && (nbSeq > 24 /* heuristic */)) {
const void* const pStart = *DTablePtr;
@@ -465,8 +465,8 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
{ unsigned tableLog;
S16 norm[MaxSeq+1];
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
- RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected);
- RETURN_ERROR_IF(tableLog > maxLog, corruption_detected);
+ RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, "");
+ RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, "");
ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);
*DTablePtr = DTableSpace;
return headerSize;
@@ -487,28 +487,28 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
DEBUGLOG(5, "ZSTD_decodeSeqHeaders");
/* check */
- RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, "");
/* SeqHead */
nbSeq = *ip++;
if (!nbSeq) {
*nbSeqPtr=0;
- RETURN_ERROR_IF(srcSize != 1, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
return 1;
}
if (nbSeq > 0x7F) {
if (nbSeq == 0xFF) {
- RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong);
+ RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
} else {
- RETURN_ERROR_IF(ip >= iend, srcSize_wrong);
+ RETURN_ERROR_IF(ip >= iend, srcSize_wrong, "");
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
}
}
*nbSeqPtr = nbSeq;
/* FSE table descriptors */
- RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong); /* minimum possible size: 1 byte for symbol encoding types */
+ 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);
@@ -521,7 +521,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
LL_base, LL_bits,
LL_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq);
- RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected);
+ RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += llhSize;
}
@@ -531,7 +531,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
OF_base, OF_bits,
OF_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq);
- RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected);
+ RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += ofhSize;
}
@@ -541,7 +541,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
ML_base, ML_bits,
ML_defaultDTable, dctx->fseEntropy,
dctx->ddictIsCold, nbSeq);
- RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected);
+ RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += mlhSize;
}
}
@@ -580,7 +580,7 @@ typedef struct {
* Precondition: *ip <= *op
* Postcondition: *op - *op >= 8
*/
-static void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
+HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
assert(*ip <= *op);
if (offset < 8) {
/* close range match, overlap */
@@ -665,15 +665,15 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
{
BYTE* const oLitEnd = op + sequence.litLength;
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
- BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
const BYTE* match = oLitEnd - sequence.offset;
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
- /* bounds checks */
- assert(oLitEnd < oMatchEnd);
- RETURN_ERROR_IF(oMatchEnd > oend, dstSize_tooSmall, "last match must fit within dstBuffer");
- RETURN_ERROR_IF(iLitEnd > litLimit, corruption_detected, "try to read beyond literal buffer");
+ /* bounds checks : careful of address space overflow in 32-bit mode */
+ RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
+ RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
+ assert(op < op + sequenceLength);
+ assert(oLitEnd < op + sequenceLength);
/* copy literals */
ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);
@@ -683,7 +683,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
/* copy Match */
if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
/* offset beyond prefix */
- RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected);
+ RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
match = dictEnd - (prefixStart-match);
if (match + sequence.matchLength <= dictEnd) {
memmove(oLitEnd, match, sequence.matchLength);
@@ -709,16 +709,27 @@ size_t ZSTD_execSequence(BYTE* op,
BYTE* const oLitEnd = op + sequence.litLength;
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
- BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
const BYTE* match = oLitEnd - sequence.offset;
- /* Errors and uncommon cases handled here. */
- assert(oLitEnd < oMatchEnd);
- if (iLitEnd > litLimit || oMatchEnd > oend_w)
+ assert(op != NULL /* Precondition */);
+ assert(oend_w < oend /* No underflow */);
+ /* Handle edge cases in a slow path:
+ * - Read beyond end of literals
+ * - Match end is within WILDCOPY_OVERLIMIT of oend
+ * - 32-bit mode and the match length overflows
+ */
+ if (UNLIKELY(
+ iLitEnd > litLimit ||
+ oMatchEnd > oend_w ||
+ (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
/* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
+ assert(op <= oLitEnd /* No overflow */);
+ assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
+ assert(oMatchEnd <= oend /* No underflow */);
assert(iLitEnd <= litLimit /* Literal length is in bounds */);
assert(oLitEnd <= oend_w /* Can wildcopy literals */);
assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
@@ -729,7 +740,7 @@ size_t ZSTD_execSequence(BYTE* op,
*/
assert(WILDCOPY_OVERLENGTH >= 16);
ZSTD_copy16(op, (*litPtr));
- if (sequence.litLength > 16) {
+ if (UNLIKELY(sequence.litLength > 16)) {
ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap);
}
op = oLitEnd;
@@ -738,7 +749,7 @@ size_t ZSTD_execSequence(BYTE* op,
/* Copy Match */
if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
/* offset beyond prefix -> go into extDict */
- RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected);
+ RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
match = dictEnd + (match - prefixStart);
if (match + sequence.matchLength <= dictEnd) {
memmove(oLitEnd, match, sequence.matchLength);
@@ -760,7 +771,7 @@ size_t ZSTD_execSequence(BYTE* op,
/* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
* without overlap checking.
*/
- if (sequence.offset >= WILDCOPY_VECLEN) {
+ if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
/* We bet on a full wildcopy for matches, since we expect matches to be
* longer than literals (in general). In silesia, ~10% of matches are longer
* than 16 bytes.
@@ -802,6 +813,14 @@ ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD)
DStatePtr->state = DInfo.nextState + lowBits;
}
+FORCE_INLINE_TEMPLATE void
+ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, ZSTD_seqSymbol const DInfo)
+{
+ U32 const nbBits = DInfo.nbBits;
+ size_t const lowBits = BIT_readBits(bitD, nbBits);
+ DStatePtr->state = DInfo.nextState + lowBits;
+}
+
/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
* offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
* bits before reloading. This value is the maximum number of bytes we read
@@ -813,25 +832,26 @@ ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD)
: 0)
typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
+typedef enum { ZSTD_p_noPrefetch=0, ZSTD_p_prefetch=1 } ZSTD_prefetch_e;
-#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
FORCE_INLINE_TEMPLATE seq_t
-ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
+ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const ZSTD_prefetch_e prefetch)
{
seq_t seq;
- U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;
- U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;
- U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;
- U32 const totalBits = llBits+mlBits+ofBits;
- U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;
- U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;
- U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;
+ ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state];
+ ZSTD_seqSymbol const mlDInfo = seqState->stateML.table[seqState->stateML.state];
+ ZSTD_seqSymbol const ofDInfo = seqState->stateOffb.table[seqState->stateOffb.state];
+ U32 const llBase = llDInfo.baseValue;
+ U32 const mlBase = mlDInfo.baseValue;
+ U32 const ofBase = ofDInfo.baseValue;
+ BYTE const llBits = llDInfo.nbAdditionalBits;
+ BYTE const mlBits = mlDInfo.nbAdditionalBits;
+ BYTE const ofBits = ofDInfo.nbAdditionalBits;
+ BYTE const totalBits = llBits+mlBits+ofBits;
/* sequence */
{ size_t offset;
- if (!ofBits)
- offset = 0;
- else {
+ if (ofBits > 1) {
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
assert(ofBits <= MaxOff);
@@ -845,59 +865,138 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
}
- }
-
- if (ofBits <= 1) {
- offset += (llBase==0);
- if (offset) {
- size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
- if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset = temp;
- } else { /* offset == 0 */
- offset = seqState->prevOffset[0];
- }
- } else {
seqState->prevOffset[2] = seqState->prevOffset[1];
seqState->prevOffset[1] = seqState->prevOffset[0];
seqState->prevOffset[0] = offset;
- }
+ } else {
+ U32 const ll0 = (llBase == 0);
+ if (LIKELY((ofBits == 0))) {
+ if (LIKELY(!ll0))
+ offset = seqState->prevOffset[0];
+ else {
+ offset = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset;
+ }
+ } else {
+ offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
+ { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset = temp;
+ } } }
seq.offset = offset;
}
- seq.matchLength = mlBase
- + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */
+ seq.matchLength = mlBase;
+ if (mlBits > 0)
+ seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
+
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
BIT_reloadDStream(&seqState->DStream);
- if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
+ if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
BIT_reloadDStream(&seqState->DStream);
/* Ensure there are enough bits to read the rest of data in 64-bit mode. */
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
- seq.litLength = llBase
- + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */
+ seq.litLength = llBase;
+ if (llBits > 0)
+ seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
+
if (MEM_32bits())
BIT_reloadDStream(&seqState->DStream);
DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
- /* ANS state update */
- ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
- ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
- ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
+ if (prefetch == ZSTD_p_prefetch) {
+ size_t const pos = seqState->pos + seq.litLength;
+ const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
+ seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
+ * No consequence though : no memory access will occur, offset is only used for prefetching */
+ seqState->pos = pos + seq.matchLength;
+ }
+
+ /* ANS state update
+ * gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo().
+ * clang-9.2.0 does 7% worse with ZSTD_updateFseState().
+ * Naturally it seems like ZSTD_updateFseStateWithDInfo() should be the
+ * better option, so it is the default for other compilers. But, if you
+ * measure that it is worse, please put up a pull request.
+ */
+ {
+#if defined(__GNUC__) && !defined(__clang__)
+ const int kUseUpdateFseState = 1;
+#else
+ const int kUseUpdateFseState = 0;
+#endif
+ if (kUseUpdateFseState) {
+ ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
+ ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
+ ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
+ } else {
+ ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llDInfo); /* <= 9 bits */
+ ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlDInfo); /* <= 9 bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
+ ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofDInfo); /* <= 8 bits */
+ }
+ }
return seq;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
+{
+ size_t const windowSize = dctx->fParams.windowSize;
+ /* No dictionary used. */
+ if (dctx->dictContentEndForFuzzing == NULL) return 0;
+ /* Dictionary is our prefix. */
+ if (prefixStart == dctx->dictContentBeginForFuzzing) return 1;
+ /* Dictionary is not our ext-dict. */
+ if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0;
+ /* Dictionary is not within our window size. */
+ if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0;
+ /* Dictionary is active. */
+ return 1;
+}
+
+MEM_STATIC void ZSTD_assertValidSequence(
+ ZSTD_DCtx const* dctx,
+ BYTE const* op, BYTE const* oend,
+ seq_t const seq,
+ BYTE const* prefixStart, BYTE const* virtualStart)
+{
+ size_t const windowSize = dctx->fParams.windowSize;
+ size_t const sequenceSize = seq.litLength + seq.matchLength;
+ BYTE const* const oLitEnd = op + seq.litLength;
+ DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
+ (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
+ assert(op <= oend);
+ assert((size_t)(oend - op) >= sequenceSize);
+ assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
+ if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
+ size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
+ /* Offset must be within the dictionary. */
+ assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
+ assert(seq.offset <= windowSize + dictSize);
+ } else {
+ /* Offset must be within our window. */
+ assert(seq.offset <= windowSize);
+ }
+}
+#endif
+
+#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
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,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
const BYTE* ip = (const BYTE*)seqStart;
const BYTE* const iend = ip + seqSize;
@@ -910,46 +1009,104 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
DEBUGLOG(5, "ZSTD_decompressSequences_body");
+ (void)frame;
/* Regen sequences */
if (nbSeq) {
seqState_t seqState;
+ size_t error = 0;
dctx->fseEntropy = 1;
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
RETURN_ERROR_IF(
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
- corruption_detected);
+ corruption_detected, "");
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
+ assert(dst != NULL);
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);
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
- DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
- op += oneSeqSize;
- } }
+#if defined(__GNUC__) && defined(__x86_64__)
+ /* Align the decompression loop to 32 + 16 bytes.
+ *
+ * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
+ * speed swings based on the alignment of the decompression loop. This
+ * performance swing is caused by parts of the decompression loop falling
+ * out of the DSB. The entire decompression loop should fit in the DSB,
+ * when it can't we get much worse performance. You can measure if you've
+ * hit the good case or the bad case with this perf command for some
+ * compressed file test.zst:
+ *
+ * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \
+ * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst
+ *
+ * If you see most cycles served out of the MITE you've hit the bad case.
+ * If you see most cycles served out of the DSB you've hit the good case.
+ * If it is pretty even then you may be in an okay case.
+ *
+ * I've been able to reproduce this issue on the following CPUs:
+ * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
+ * Use Instruments->Counters to get DSB/MITE cycles.
+ * I never got performance swings, but I was able to
+ * go from the good case of mostly DSB to half of the
+ * cycles served from MITE.
+ * - Coffeelake: Intel i9-9900k
+ *
+ * I haven't been able to reproduce the instability or DSB misses on any
+ * of the following CPUS:
+ * - Haswell
+ * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH
+ * - Skylake
+ *
+ * If you are seeing performance stability this script can help test.
+ * It tests on 4 commits in zstd where I saw performance change.
+ *
+ * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
+ */
+ __asm__(".p2align 5");
+ __asm__("nop");
+ __asm__(".p2align 4");
+#endif
+ for ( ; ; ) {
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_noPrefetch);
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
+#endif
+ DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
+ BIT_reloadDStream(&(seqState.DStream));
+ /* gcc and clang both don't like early returns in this loop.
+ * gcc doesn't like early breaks either.
+ * Instead save an error and report it at the end.
+ * When there is an error, don't increment op, so we don't
+ * overwrite.
+ */
+ if (UNLIKELY(ZSTD_isError(oneSeqSize))) error = oneSeqSize;
+ else op += oneSeqSize;
+ if (UNLIKELY(!--nbSeq)) break;
+ }
/* 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);
+ if (ZSTD_isError(error)) return error;
+ 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]); }
}
/* last literal segment */
{ size_t const lastLLSize = litEnd - litPtr;
- RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall);
- memcpy(op, litPtr, lastLLSize);
- op += lastLLSize;
+ RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
+ if (op != NULL) {
+ memcpy(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
}
return op-ostart;
@@ -959,99 +1116,21 @@ static size_t
ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
-
-
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
-FORCE_INLINE_TEMPLATE seq_t
-ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
-{
- seq_t seq;
- U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;
- U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;
- U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;
- U32 const totalBits = llBits+mlBits+ofBits;
- U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;
- U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;
- U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;
-
- /* sequence */
- { size_t offset;
- if (!ofBits)
- offset = 0;
- else {
- ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
- ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
- assert(ofBits <= MaxOff);
- if (MEM_32bits() && longOffsets) {
- U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
- offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
- if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
- if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
- } else {
- offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
- }
- }
-
- if (ofBits <= 1) {
- offset += (llBase==0);
- if (offset) {
- size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
- if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset = temp;
- } else {
- offset = seqState->prevOffset[0];
- }
- } else {
- seqState->prevOffset[2] = seqState->prevOffset[1];
- seqState->prevOffset[1] = seqState->prevOffset[0];
- seqState->prevOffset[0] = offset;
- }
- seq.offset = offset;
- }
-
- seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
- if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
- BIT_reloadDStream(&seqState->DStream);
- if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
- BIT_reloadDStream(&seqState->DStream);
- /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
- ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
-
- seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
- if (MEM_32bits())
- BIT_reloadDStream(&seqState->DStream);
-
- { size_t const pos = seqState->pos + seq.litLength;
- const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
- seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
- * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */
- seqState->pos = pos + seq.matchLength;
- }
-
- /* ANS state update */
- ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
- ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
- ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
-
- return seq;
-}
-
FORCE_INLINE_TEMPLATE size_t
ZSTD_decompressSequencesLong_body(
ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
const BYTE* ip = (const BYTE*)seqStart;
const BYTE* const iend = ip + seqSize;
@@ -1063,6 +1142,7 @@ ZSTD_decompressSequencesLong_body(
const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
+ (void)frame;
/* Regen sequences */
if (nbSeq) {
@@ -1078,36 +1158,45 @@ ZSTD_decompressSequencesLong_body(
seqState.prefixStart = prefixStart;
seqState.pos = (size_t)(op-prefixStart);
seqState.dictEnd = dictEnd;
+ assert(dst != NULL);
assert(iend >= ip);
RETURN_ERROR_IF(
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
- corruption_detected);
+ corruption_detected, "");
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
/* prepare in advance */
for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
- sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
+ sequences[seqNb] = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_prefetch);
PREFETCH_L1(sequences[seqNb].match); PREFETCH_L1(sequences[seqNb].match + sequences[seqNb].matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
}
- RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected);
+ RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
/* decode and decompress */
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb<nbSeq) ; seqNb++) {
- seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_prefetch);
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
+#endif
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
PREFETCH_L1(sequence.match); PREFETCH_L1(sequence.match + sequence.matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
sequences[seqNb & STORED_SEQS_MASK] = sequence;
op += oneSeqSize;
}
- RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected);
+ RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
/* finish queue */
seqNb -= seqAdvance;
for ( ; seqNb<nbSeq ; seqNb++) {
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[seqNb&STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
+#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
+ assert(!ZSTD_isError(oneSeqSize));
+ if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
+#endif
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
op += oneSeqSize;
}
@@ -1118,9 +1207,11 @@ ZSTD_decompressSequencesLong_body(
/* last literal segment */
{ size_t const lastLLSize = litEnd - litPtr;
- RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall);
- memcpy(op, litPtr, lastLLSize);
- op += lastLLSize;
+ RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
+ if (op != NULL) {
+ memcpy(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
}
return op-ostart;
@@ -1130,9 +1221,10 @@ static size_t
ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
@@ -1146,9 +1238,10 @@ DONT_VECTORIZE
ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
@@ -1157,9 +1250,10 @@ static TARGET_ATTRIBUTE("bmi2") size_t
ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
@@ -1169,21 +1263,23 @@ typedef size_t (*ZSTD_decompressSequences_t)(
ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset);
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame);
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
static size_t
ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
DEBUGLOG(5, "ZSTD_decompressSequences");
#if DYNAMIC_BMI2
if (dctx->bmi2) {
- return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif
- return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
@@ -1198,15 +1294,16 @@ static size_t
ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
- const ZSTD_longOffset_e isLongOffset)
+ const ZSTD_longOffset_e isLongOffset,
+ const int frame)
{
DEBUGLOG(5, "ZSTD_decompressSequencesLong");
#if DYNAMIC_BMI2
if (dctx->bmi2) {
- return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif
- return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
}
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
@@ -1240,7 +1337,6 @@ ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
}
#endif
-
size_t
ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
@@ -1256,7 +1352,7 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))));
DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
- RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong);
+ RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
/* Decode literals section */
{ size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
@@ -1282,6 +1378,8 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
ip += seqHSize;
srcSize -= seqHSize;
+ RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
+
#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
if ( !usePrefetchDecoder
@@ -1300,17 +1398,28 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
if (usePrefetchDecoder)
#endif
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
#endif
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
/* else */
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
#endif
}
}
+void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
+{
+ if (dst != dctx->previousDstEnd) { /* not contiguous */
+ dctx->dictEnd = dctx->previousDstEnd;
+ dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
+ dctx->prefixStart = dst;
+ dctx->previousDstEnd = dst;
+ }
+}
+
+
size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.h b/thirdparty/zstd/decompress/zstd_decompress_block.h
index 7e92960410..bf39b7350c 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -16,8 +16,8 @@
* Dependencies
*********************************************************/
#include <stddef.h> /* size_t */
-#include "zstd.h" /* DCtx, and some public functions */
-#include "zstd_internal.h" /* blockProperties_t, and some public functions */
+#include "../zstd.h" /* DCtx, and some public functions */
+#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */
#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */
diff --git a/thirdparty/zstd/decompress/zstd_decompress_internal.h b/thirdparty/zstd/decompress/zstd_decompress_internal.h
index ccbdfa090f..9ad96c5548 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_internal.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -19,8 +19,8 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include "mem.h" /* BYTE, U16, U32 */
-#include "zstd_internal.h" /* ZSTD_seqSymbol */
+#include "../common/mem.h" /* BYTE, U16, U32 */
+#include "../common/zstd_internal.h" /* ZSTD_seqSymbol */
@@ -95,6 +95,11 @@ typedef enum {
ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
} ZSTD_dictUses_e;
+typedef enum {
+ ZSTD_obm_buffered = 0, /* Buffer the output */
+ ZSTD_obm_stable = 1 /* ZSTD_outBuffer is stable */
+} ZSTD_outBufferMode_e;
+
struct ZSTD_DCtx_s
{
const ZSTD_seqSymbol* LLTptr;
@@ -147,10 +152,19 @@ struct ZSTD_DCtx_s
U32 legacyVersion;
U32 hostageByte;
int noForwardProgress;
+ ZSTD_outBufferMode_e outBufferMode;
+ ZSTD_outBuffer expectedOutBuffer;
/* workspace */
BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
+
+ size_t oversizedDuration;
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ void const* dictContentBeginForFuzzing;
+ void const* dictContentEndForFuzzing;
+#endif
}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
@@ -160,7 +174,7 @@ struct ZSTD_DCtx_s
/*! ZSTD_loadDEntropy() :
* dict : must point at beginning of a valid zstd dictionary.
- * @return : size of entropy tables read */
+ * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */
size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
const void* const dict, size_t const dictSize);
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
index 72080ea87e..8c6fc6ae90 100644
--- a/thirdparty/zstd/zstd.h
+++ b/thirdparty/zstd/zstd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -72,7 +72,7 @@ extern "C" {
/*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 4
-#define ZSTD_VERSION_RELEASE 4
+#define ZSTD_VERSION_RELEASE 5
#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 */
@@ -274,7 +274,10 @@ typedef enum {
* Default level is ZSTD_CLEVEL_DEFAULT==3.
* Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT.
* Note 1 : it's possible to pass a negative compression level.
- * Note 2 : setting a level resets all other compression parameters to default */
+ * Note 2 : setting a level does not automatically set all other compression parameters
+ * to default. Setting this will however eventually dynamically impact the compression
+ * parameters which have not been manually set. The manually set
+ * ones will 'stick'. */
/* Advanced compression parameters :
* It's possible to pin down compression parameters to some specific values.
* In which case, these values are no longer dynamically selected by the compressor */
@@ -519,11 +522,13 @@ typedef enum {
/* note : additional experimental parameters are also available
* within the experimental section of the API.
* At the time of this writing, they include :
- * ZSTD_c_format
+ * ZSTD_d_format
+ * ZSTD_d_stableOutBuffer
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly
*/
- ZSTD_d_experimentalParam1=1000
+ ZSTD_d_experimentalParam1=1000,
+ ZSTD_d_experimentalParam2=1001
} ZSTD_dParameter;
@@ -763,7 +768,7 @@ ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
/* This function is redundant with the advanced API and equivalent to:
*
- * ZSTD_DCtx_reset(zds);
+ * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
* ZSTD_DCtx_refDDict(zds, NULL);
*/
ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
@@ -1263,23 +1268,28 @@ ZSTDLIB_API size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
***************************************/
/*! ZSTD_estimate*() :
- * These functions make it possible to estimate memory usage of a future
- * {D,C}Ctx, before its creation.
+ * These functions make it possible to estimate memory usage
+ * of a future {D,C}Ctx, before its creation.
+ *
+ * ZSTD_estimateCCtxSize() will provide a memory budget large enough
+ * for any compression level up to selected one.
+ * Note : Unlike ZSTD_estimateCStreamSize*(), this estimate
+ * does not include space for a window buffer.
+ * Therefore, the estimation is only guaranteed for single-shot compressions, not streaming.
+ * The estimate will assume the input may be arbitrarily large,
+ * which is the worst case.
*
- * ZSTD_estimateCCtxSize() will provide a budget large enough for any
- * compression level up to selected one. Unlike ZSTD_estimateCStreamSize*(),
- * this estimate does not include space for a window buffer, so this estimate
- * is guaranteed to be enough for single-shot compressions, but not streaming
- * compressions. It will however assume the input may be arbitrarily large,
- * which is the worst case. If srcSize is known to always be small,
- * ZSTD_estimateCCtxSize_usingCParams() can provide a tighter estimation.
- * ZSTD_estimateCCtxSize_usingCParams() can be used in tandem with
- * ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCCtxSize_usingCCtxParams() can be used in tandem with
- * ZSTD_CCtxParams_setParameter().
+ * When srcSize can be bound by a known and rather "small" value,
+ * this fact can be used to provide a tighter estimation
+ * because the CCtx compression context will need less memory.
+ * This tighter estimation can be provided by more advanced functions
+ * ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(),
+ * and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter().
+ * Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits.
*
- * Note: only single-threaded compression is supported. This function will
- * return an error code if ZSTD_c_nbWorkers is >= 1. */
+ * Note 2 : only single-threaded compression is supported.
+ * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1.
+ */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
@@ -1642,6 +1652,37 @@ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowS
* allowing selection between ZSTD_format_e input compression formats
*/
#define ZSTD_d_format ZSTD_d_experimentalParam1
+/* ZSTD_d_stableOutBuffer
+ * Experimental parameter.
+ * Default is 0 == disabled. Set to 1 to enable.
+ *
+ * Tells the decompressor that the ZSTD_outBuffer will ALWAYS be the same
+ * between calls, except for the modifications that zstd makes to pos (the
+ * caller must not modify pos). This is checked by the decompressor, and
+ * decompression will fail if it ever changes. Therefore the ZSTD_outBuffer
+ * MUST be large enough to fit the entire decompressed frame. This will be
+ * checked when the frame content size is known. The data in the ZSTD_outBuffer
+ * in the range [dst, dst + pos) MUST not be modified during decompression
+ * or you will get data corruption.
+ *
+ * When this flags is enabled zstd won't allocate an output buffer, because
+ * it can write directly to the ZSTD_outBuffer, but it will still allocate
+ * an input buffer large enough to fit any compressed block. This will also
+ * avoid the memcpy() from the internal output buffer to the ZSTD_outBuffer.
+ * If you need to avoid the input buffer allocation use the buffer-less
+ * streaming API.
+ *
+ * NOTE: So long as the ZSTD_outBuffer always points to valid memory, using
+ * this flag is ALWAYS memory safe, and will never access out-of-bounds
+ * memory. However, decompression WILL fail if you violate the preconditions.
+ *
+ * WARNING: The data in the ZSTD_outBuffer in the range [dst, dst + pos) MUST
+ * not be modified during decompression or you will get data corruption. This
+ * is because zstd needs to reference data in the ZSTD_outBuffer to regenerate
+ * matches. Normally zstd maintains its own buffer for this purpose, but passing
+ * this flag tells zstd to use the user provided buffer.
+ */
+#define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2
/*! ZSTD_DCtx_setFormat() :
* Instruct the decoder context about what kind of data to decode next.